home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OctaMED Sound Studio 1
/
OctaMED SoundStudio V1.iso
/
soundstudio v1
/
programmers
/
med-mixasm.a
< prev
next >
Wrap
Text File
|
1996-06-18
|
122KB
|
5,517 lines
; ***********************************************************
; **** OctaMED Pro source code ****
; **** Written by Teijo Kinnunen ****
; **** Copyright 1995-1996 Teijo Kinnunen & RBF Software ****
; **** All rights reserved. ****
; **** Mixing routines ****
; ***********************************************************
; This file is used as such both by OctaMED and the external
; player routines. These flags specify the correct mode.
; This must be 0 always (except when compiling OctaMED)
OCTAMED_INTERN EQU 0
; Set either or both to 1
SUPPORT_000 EQU 1
SUPPORT_020 EQU 1
; Set to 1 if you need smoothing (usually you won't...I suppose)
SUPPORT_SMOOTH EQU 0
MC68020
MC68881
IFEQ OCTAMED_INTERN
OUTPUT med-mixasm.o
ELSEIF
OUTPUT obj/med-mixasm.o
ENDC
LINKOBJ
INCLUDE "medtrkdata.i"
IFEQ OCTAMED_INTERN
INCLUDE "chinfo.i"
ENDC
BOPT O+,wo-
XREF _buffsize
XREF _chinfo
; -------------------------------------------------------------------
; These register variables are used by all mixing routines.
; -------------------------------------------------------------------
; D2 = ci_offset
; D4 = ci_fraction
; D5 = ci_advance
; D6 = ci_advfract
IFNE OCTAMED_INTERN
XREF _UtilityBase
ELSEIF
XREF UtBase
ENDC
IFNE SUPPORT_000
; -------------------------------------------------------------------
; MixSample(WORD *dest,UWORD mixlen) (a1,d2)
; -------------------------------------------------------------------
; Note: mixlen may not be > 32767!!
MixSample
movem.l d2-d7/a2-a6,-(sp) ;note: (sp).l = mixlen
; --- Track loop:
move.w m_channels(pc),d7
movea.l _chinfo,a5
subq.w #1,d7
msm_chloop tst.b ci_flags(a5) ;CHFLAG_MUTED?
bmi.w msm_chloopend
moveq #0,d3 ;the upper word used by some mix routines
move.w 2(sp),d3 ;d3 = mixlen
; --- load registers for mixing
movem.l ci_mixregs(a5),d2/d4/d5/d6/a4
movea.l a1,a2 ;destination pointer
btst #CHFLAGB_BACKW,ci_flags(a5) ;backwards?
bne.w msm_backwards
msm_loop2 ;while(left_to_mix > 0)...
move.l d5,d1 ;d1 = advance
; Tests whether current sample end is reached within remaining
; space in mixing buffer.
move.w d3,d0
mulu d6,d0 ;advfract * size...
add.l d4,d0 ;... + fraction
clr.w d0
swap d0
mulu d3,d1 ;advance * size
add.l d0,d1
move.l ci_endoffset(a5),d0
sub.l d2,d0 ;d0 = endoffset - offset
ble.s msm_mutechan ;loop too short
cmp.l d0,d1
bhs.s msm_calcsize
; Sample end won't be reached... just fill the remaining mix buffer
; size straight away.
move.w d3,d0
jsr (a4)
cmp.l ci_endoffset(a5),d2
blo.s msm_savereg
moveq #0,d3
bra.s msm_sampleend
; Sample end will be reached: calculate how many bytes can be mixed.
; (This calculation requires that remaining buffer size fits in a word.)
msm_calcsize swap d0 ;d0 already contains endoffs - offs
clr.w d0 ;<< 16
sub.l d4,d0 ; - fraction
subq.l #1,d0 ; - 1
move.w d5,d1 ;advance..
swap d1
move.w d6,d1 ;advfract.
; 32-bit division required... utility.library used for 68000
; compatibility
IFNE OCTAMED_INTERN
movea.l _UtilityBase,a0
ELSEIF
movea.l UtBase,a0
ENDC
jsr -$9C(a0) ;UDivMod32()
addq.w #1,d0
sub.w d0,d3 ;left_to_mix -= passsize
jsr (a4) ;mix/skip
cmp.l ci_endoffset(a5),d2
bhs.s msm_sampleend
tst.w d3
beq.s msm_savereg
msm_sampleend btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s msm_mutechan
btst #CHFLAGB_PINGPONG,ci_flags(a5)
bne.s msm_pingpong
sub.l ci_restartoffset(a5),d2
move.l ci_newstart_addr(a5),d0
beq.s msm_loopend
move.l d0,ci_sample_start(a5)
move.l ci_newendoffset(a5),d0
move.l d0,ci_endoffset(a5)
move.l d0,ci_restartoffset(a5)
msm_loopend tst.w d3 ;left_to_mix
bgt.s msm_loop2
bra.s msm_savereg
msm_mutechan bset #CHFLAGB_MUTED,ci_flags(a5)
; --- save registers after mixing
msm_savereg
movem.l d2/d4,ci_mixregs(a5)
msm_chloopend adda.w #ci_sizeof,a5
dbra d7,msm_chloop
movem.l (sp)+,d2-d7/a2-a6
rts
; swap mixing routine (change direction)
msm_pingpong move.l ci_altmixroutine(a5),d0
move.l a4,ci_altmixroutine(a5)
movea.l d0,a4
move.l d0,ci_mixroutine(a5)
bchg #CHFLAGB_BACKW,ci_flags(a5)
; loop beginning -> loop end
move.l ci_endoffset(a5),d0
; turn pointer to the other side of the previous end offset
sub.l d0,d2
neg.l d2
add.l d0,d2
sub.l ci_restartoffset(a5),d0
move.l d0,ci_endoffset(a5)
tst.w d3
beq.s msm_savereg
msm_backwards
msmb_loop2 ;while(left_to_mix > 0)...
move.l d5,d1 ;d1 = advance
; Tests whether current sample end is reached within remaining
; space in mixing buffer.
move.w d3,d0
mulu d6,d0 ;advfract * size...
add.l d4,d0 ;... + fraction
clr.w d0
swap d0
mulu d3,d1 ;advance * size
add.l d0,d1
move.l d2,d0
sub.l ci_endoffset(a5),d0 ;d0 = offset - endoffset
ble.s msm_mutechan ;loop too short
cmp.l d0,d1
bhs.s msmb_calcsize
; Sample end won't be reached... just fill the remaining mix buffer
; size straight away.
move.w d3,d0
jsr (a4)
cmp.l ci_endoffset(a5),d2
bgt.s msm_savereg
moveq #0,d3
bra.s msmb_sampleend
; Sample end will be reached: calculate how many bytes can be mixed.
; (This calculation requires that remaining buffer size fits in a word.)
msmb_calcsize swap d0 ;d0 already contains endoffs - offs
clr.w d0 ;<< 16
sub.l d4,d0 ; - fraction
subq.l #1,d0 ; - 1
move.w d5,d1 ;advance..
swap d1
move.w d6,d1 ;advfract.
; 32-bit division required... utility.library used for 68000
; compatibility
IFNE OCTAMED_INTERN
movea.l _UtilityBase,a0
ELSEIF
movea.l UtBase,a0
ENDC
jsr -$9C(a0) ;UDivMod32()
addq.w #1,d0
sub.w d0,d3 ;left_to_mix -= passsize
jsr (a4) ;mix/skip
cmp.l ci_endoffset(a5),d2
ble.s msmb_sampleend
tst.w d3
beq.s msm_savereg
msmb_sampleend btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s msm_mutechan
btst #CHFLAGB_PINGPONG,ci_flags(a5)
bne.s msm_pingpong2
add.l ci_restartoffset(a5),d2
tst.w d3 ;left_to_mix
bgt.s msmb_loop2
bra.s msm_savereg
; swap mixing routine (change direction)
msm_pingpong2 move.l ci_altmixroutine(a5),d0
move.l a4,ci_altmixroutine(a5)
movea.l d0,a4
move.l d0,ci_mixroutine(a5)
bchg #CHFLAGB_BACKW,ci_flags(a5)
; loop beginning -> loop end
move.l ci_endoffset(a5),d0
; turn pointer to the other side of the previous end offset
sub.l d0,d2
neg.l d2
add.l d0,d2
add.l ci_restartoffset(a5),d0
move.l d0,ci_endoffset(a5)
tst.w d3
bgt.s msm_loop2
bra.s msm_savereg
ENDC
IFNE SUPPORT_020
; -------------------------------------------------------------------
; MixSample_020(WORD *dest,UWORD mixlen) (a1,d2)
; -------------------------------------------------------------------
MixSample_020 movem.l d2-d7/a2-a6,-(sp) ;note: (sp).l = mixlen
; --- Track loop:
move.w m_channels(pc),d7
movea.l _chinfo,a5
subq.w #1,d7
msm2_chloop tst.b ci_flags(a5) ;CHFLAG_MUTED?
bmi.w msm2_chloopend
moveq #0,d3 ;the upper word used by some mix routines
move.w 2(sp),d3 ;d3 = mixlen
; --- load registers for mixing
movem.l ci_mixregs(a5),d2/d4/d5/d6/a4
movea.l a1,a2 ;destination pointer
btst #CHFLAGB_BACKW,ci_flags(a5) ;backwards?
bne.w msm2_backwards
msm2_loop2 ;while(left_to_mix > 0)...
move.l d5,d1 ;d1 = advance
; Tests whether current sample end is reached within remaining
; space in mixing buffer.
ext.l d3
swap d1
move.w d6,d1
mulu.l d3,d0:d1
add.l d4,d1 ;add fraction
move.w d0,d1
swap d1
move.l ci_endoffset(a5),d0
sub.l d2,d0 ;d0 = endoffset - offset
ble.s msm2_mutechan ;loop too short
cmp.l d0,d1
bhs.s msm2_calcsize
; Sample end won't be reached... just fill the remaining mix buffer
; size straight away.
move.w d3,d0
jsr (a4)
cmp.l ci_endoffset(a5),d2
blo.s msm2_savereg
moveq #0,d3
bra.s msm2_sampleend
; Sample end will be reached: calculate how many bytes can be mixed.
; (This calculation requires that remaining buffer size fits in a word.)
msm2_calcsize swap d0 ;d0 already contains endoffs - offs
clr.w d0 ;<< 16
sub.l d4,d0 ; - fraction
subq.l #1,d0 ; - 1
move.w d5,d1 ;advance..
swap d1
move.w d6,d1 ;advfract.
divu.l d1,d0
addq.w #1,d0
sub.w d0,d3 ;left_to_mix -= passsize
jsr (a4) ;mix/skip
cmp.l ci_endoffset(a5),d2
bhs.s msm2_sampleend
tst.w d3
beq.s msm2_savereg
msm2_sampleend btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s msm2_mutechan
btst #CHFLAGB_PINGPONG,ci_flags(a5)
bne.s msm2_pingpong
sub.l ci_restartoffset(a5),d2
move.l ci_newstart_addr(a5),d0
beq.s msm2_loopend
move.l d0,ci_sample_start(a5)
move.l ci_newendoffset(a5),d0
move.l d0,ci_endoffset(a5)
move.l d0,ci_restartoffset(a5)
msm2_loopend tst.w d3 ;left_to_mix
bgt.s msm2_loop2
bra.s msm2_savereg
msm2_mutechan bset #CHFLAGB_MUTED,ci_flags(a5)
; --- save registers after mixing
msm2_savereg
movem.l d2/d4,ci_mixregs(a5)
msm2_chloopend adda.w #ci_sizeof,a5
dbra d7,msm2_chloop
movem.l (sp)+,d2-d7/a2-a6
rts
; swap mixing routine (change direction)
msm2_pingpong move.l ci_altmixroutine(a5),d0
move.l a4,ci_altmixroutine(a5)
movea.l d0,a4
move.l d0,ci_mixroutine(a5)
bchg #CHFLAGB_BACKW,ci_flags(a5)
; loop beginning -> loop end
move.l ci_endoffset(a5),d0
; turn pointer to the other side of the previous end offset
sub.l d0,d2
neg.l d2
add.l d0,d2
sub.l ci_restartoffset(a5),d0
move.l d0,ci_endoffset(a5)
tst.w d3
beq.s msm2_savereg
msm2_backwards
msmb2_loop2 ;while(left_to_mix > 0)...
move.l d5,d1 ;d1 = advance
; Tests whether current sample end is reached within remaining
; space in mixing buffer.
ext.l d3
swap d1
move.w d6,d1
mulu.l d3,d0:d1
move.w d0,d1
swap d1
move.l d2,d0
sub.l ci_endoffset(a5),d0 ;d0 = offset - endoffset
ble.s msm2_mutechan ;loop too short
cmp.l d0,d1
bhs.s msmb2_calcsize
; Sample end won't be reached... just fill the remaining mix buffer
; size straight away.
move.w d3,d0
jsr (a4)
cmp.l ci_endoffset(a5),d2
bgt.s msm2_savereg
moveq #0,d3
bra.s msmb2_sampleend
; Sample end will be reached: calculate how many bytes can be mixed.
; (This calculation requires that remaining buffer size fits in a word.)
msmb2_calcsize swap d0 ;d0 already contains endoffs - offs
clr.w d0 ;<< 16
sub.l d4,d0 ; - fraction
subq.l #1,d0 ; - 1
move.w d5,d1 ;advance..
swap d1
move.w d6,d1 ;advfract.
divu.l d1,d0
addq.w #1,d0
sub.w d0,d3 ;left_to_mix -= passsize
jsr (a4) ;mix/skip
cmp.l ci_endoffset(a5),d2
ble.s msmb2_sampleend
tst.w d3
beq.s msm2_savereg
msmb2_sampleend btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s msm2_mutechan
btst #CHFLAGB_PINGPONG,ci_flags(a5)
bne.s msm2_pingpong2
add.l ci_restartoffset(a5),d2
tst.w d3 ;left_to_mix
bgt.s msmb2_loop2
bra.s msm2_savereg
; swap mixing routine (change direction)
msm2_pingpong2 move.l ci_altmixroutine(a5),d0
move.l a4,ci_altmixroutine(a5)
movea.l d0,a4
move.l d0,ci_mixroutine(a5)
bchg #CHFLAGB_BACKW,ci_flags(a5)
; loop beginning -> loop end
move.l ci_endoffset(a5),d0
; turn pointer to the other side of the previous end offset
sub.l d0,d2
neg.l d2
add.l d0,d2
add.l ci_restartoffset(a5),d0
move.l d0,ci_endoffset(a5)
tst.w d3
bgt.s msm2_loop2
bra.s msm2_savereg
ENDC
IFNE SUPPORT_000
; Skip mix pass (just advance pointers)
Skip move.w d0,d1 ;passsize...
mulu d6,d0 ;* advfract
mulu d5,d1 ;* advance
add.l d1,d2 ;offset += passsize * advance
add.w d0,d4 ;add fraction
clr.w d0
swap d0 ;get upper word
addx.l d0,d2 ;add to offset.
rts
Skipb move.w d0,d1 ;passsize...
mulu d6,d0 ;* advfract
mulu d5,d1 ;* advance
sub.l d1,d2 ;offset -= passsize * advance
add.w d0,d4 ;add fraction
clr.w d0
swap d0 ;get upper word
subx.l d0,d2 ;add to offset.
rts
ENDC
IFNE SUPPORT_020
Skip_020 move.w d5,d1
swap d1
move.w d6,d1
ext.l d0
mulu.l d0,d0:d1
add.w d1,d4 ,add fraction
move.w d0,d1
swap d1
addx.l d1,d2 ;add offset
rts
Skipb_020 move.w d5,d1
swap d1
move.w d6,d1
ext.l d0
mulu.l d0,d0:d1
add.w d1,d4 ,add fraction
move.w d0,d1
swap d1
subx.l d1,d2 ;add offset
rts
ENDC
IFNE SUPPORT_SMOOTH
; -------------------------------------------------------------------
; Mixing routines: Mono, 8/16-bit, forwards/backwards, smooth
; -------------------------------------------------------------------
addq.l #1,d2
rts
GetNextSample move.l ci_endoffset(a5),d3
subq.l #1,d3
cmp.l d3,d2
bhs.s gns_end
moveq #0,d3
move.b 1(a6,d2.l),d3
bra.s gns_noloop
gns_end moveq #0,d3
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s gns_noloop
move.l d2,-(sp)
sub.l ci_restartoffset(a5),d2
tst.l ci_newstart_addr(a5)
beq.s 1$
move.l a6,-(sp)
movea.l ci_newstart_addr(a5),a6
btst #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
beq.s 3$
adda.l ci_rightch_offs(a5),a6
3$ move.b 1(a6,d2.l),d3
move.l (sp)+,a6
bra.s 2$
1$ move.b 1(a6,d2.l),d3
2$ move.l (sp)+,d2
gns_noloop add.w d3,d3
move.w 0(a3,d3.w),d3
btst #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
bne.s 1$
move.w d3,ci_nextsample(a5)
rts
1$ move.w d3,ci_nextsample_r(a5)
rts
subq.l #1,d2
rts
GetNextSampleB move.l ci_endoffset(a5),d3
addq.l #1,d3
cmp.l d3,d2
ble.s gnsb_end
moveq #0,d3
move.b -1(a6,d2.l),d3
bra.s gns_noloop
gnsb_end moveq #0,d3
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s gns_noloop
move.l d2,-(sp)
add.l ci_restartoffset(a5),d2
move.b -1(a6,d2.l),d3
move.l (sp)+,d2
bra.s gns_noloop
subq.l #1,d2
rts
GetNextSample_16B
move.l ci_endoffset(a5),d3
addq.l #1,d3
cmp.l d3,d2
ble.s gnsb16_end
move.l d2,d3
add.l d3,d3
move.w -2(a6,d3.l),d3
bra.s gns16_noloop
gnsb16_end moveq #0,d3
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s gns16_noloop
move.l d2,-(sp)
add.l ci_restartoffset(a5),d2
move.l d2,d3
add.l d3,d3
move.w 2(a6,d3.l),d3
move.l (sp)+,d2
bra.s gns16_noloop
addq.l #1,d2
rts
GetNextSample_16
move.l ci_endoffset(a5),d3
subq.l #1,d3
cmp.l d3,d2
bhs.s gns16_end
move.l d2,d3
add.l d3,d3
move.w 2(a6,d3.l),d3
bra.s gns16_noloop
gns16_end moveq #0,d3
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s gns16_noloop
move.l d2,-(sp)
sub.l ci_restartoffset(a5),d2
move.l d2,d3
add.l d3,d3
tst.l ci_newstart_addr(a5)
beq.s 1$
move.l a6,-(sp)
movea.l ci_newstart_addr(a5),a6
move.w 2(a6,d3.l),d3
move.l (sp)+,a6
bra.s 2$
1$ move.w 2(a6,d3.l),d3
2$ move.l (sp)+,d2
gns16_noloop asr.w d7,d3
btst #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
bne.s 1$
move.w d3,ci_nextsample(a5)
rts
1$ move.w d3,ci_nextsample_r(a5)
rts
rts
sMIX_mono8 movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
subq.w #1,d0
tst.w d5
bne.s sMIX_avg
movem.l d3/d5/a4,-(sp)
bsr.w GetCurrS_8
move.w d1,ci_currsample(a5)
lea GetNextSample(pc),a4
bsr.w sMIX_monoloop
movem.l (sp)+,d3/d5/a4
rts
sMIX_avg movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1(pc),a4
bsr.w sMIX_avgmono
movem.l (sp)+,a1/a4
rts
sMIXb_mono8 movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
subq.w #1,d0
tst.w d5
bne.s sMIXb_avg
movem.l d3/d5/a4,-(sp)
bsr.w GetCurrS_8
move.w d1,ci_currsample(a5)
lea GetNextSampleB(pc),a4
bsr.w sMIX_monoloop
movem.l (sp)+,d3/d5/a4
rts
sMIXb_avg movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1b(pc),a4
bsr.w sMIX_avgmono
movem.l (sp)+,a1/a4
rts
sMIX_mono16 movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s sMIX_avg16
movem.l d3/d5/d7/a4,-(sp)
move.w ci_volshift_l(a5),d7
bsr.w GetCurrS_16
move.w d1,ci_currsample(a5)
lea GetNextSample_16(pc),a4
bsr.s sMIX_monoloop
movem.l (sp)+,d3/d5/d7/a4
rts
sMIX_avg16 movem.l a1/a4/d7,-(sp)
lea GetS_1_16(pc),a4
lea GetCurrS_16(pc),a1
move.w ci_volshift_l(a5),d7
bsr.w sMIX_avgmono
movem.l (sp)+,a1/a4/d7
rts
sMIXb_mono16 movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s sMIXb_avg16
movem.l d3/d5/d7/a4,-(sp)
move.w ci_volshift_l(a5),d7
bsr.w GetCurrS_16
move.w d1,ci_currsample(a5)
lea GetNextSample_16B(pc),a4
bsr.s sMIX_monoloop
movem.l (sp)+,d3/d5/d7/a4
rts
sMIXb_avg16 movem.l a1/a4/d7,-(sp)
lea GetS_1_16b(pc),a4
lea GetCurrS_16(pc),a1
move.w ci_volshift_l(a5),d7
bsr.w sMIX_avgmono
movem.l (sp)+,a1/a4/d7
rts
sMIX_monoloop jsr (a4)
1$ move.w ci_currsample(a5),d1
ext.l d1
move.w ci_prevsample(a5),d5
ext.l d5
sub.l d1,d5
neg.l d5 ;f' at fract 0 (curr - prev)
move.w ci_nextsample(a5),d3
ext.l d3
sub.l d1,d3 ;f' at fract $FFFF (next - curr)
sub.l d5,d3 ;f'' during the curr. sample
lsr.l #2,d3
lsr.w #1,d4
muls d4,d3 ;get f'' at curr. fract
roxl.w #1,d4
swap d3 ;/ 0x10000
ext.l d3
asl.l #2,d3
add.l d5,d3 ;add initial f' at fract 0
lsr.l #2,d3
lsr.w #1,d4
muls d4,d3
roxl.w #1,d4
asl.l #3,d3
swap d3 ;/ 0x10000
move.w ci_prevsample(a5),d5
ext.l d5
add.l d5,d1
lsr.l #1,d1
add.w d3,d1 ;add to initial sample value
bvc.s 2$
move.w ci_currsample(a5),d1
2$ add.w d1,(a2)+
add.w d6,d4 ;actually advance fraction
bcc.s 4$
jsr -4(a4) ;add (or subtract) one to offset
move.l ci_currsample(a5),ci_prevsample(a5)
jsr (a4)
4$ dbra d0,1$
rts
GetCurrS_8 moveq #0,d1
move.b 0(a6,d2.l),d1 ;current sample
add.w d1,d1
move.w 0(a3,d1.w),d1
rts
GetCurrS_16 move.l d2,d1
add.l d1,d1
move.w 0(a6,d1.l),d1
asr.w d7,d1
rts
sMIX_avgmono move.l d3,-(sp)
1$ move.w d4,d3
not.w d3 ;what's left of current sample
jsr (a1)
lsr.w #1,d3
muls d1,d3
asr.l #7,d3 ;/ 256..
move.w d5,-(sp)
move.w d6,-(sp)
move.w d4,d6
not.w d6
lsr.w #8,d6 ;divisor
add.l -4(a4),d2 ;advance offset
subq.w #2,d5
bmi.s 2$ ;no full samples to skip
3$ jsr (a4)
add.l -4(a4),d2 ;advance offset
swap d1
asr.l #8,d1
add.l d1,d3
dbra d5,3$
2$ add.w (sp),d4 ;d6 = (sp) = advfract
bcc.s 4$
jsr (a4)
add.l -4(a4),d2 ;advance offset
swap d1
asr.l #8,d1
add.l d1,d3
4$ jsr 4(a4) ;get last (partial) sample
move.w d4,d5
lsr.w #8,d5
add.w d5,d6
move.w d4,d5
lsr.w #1,d5
muls d5,d1
asr.l #7,d1
add.l d1,d3
divs d6,d3 ;divide to get average
move.w (sp)+,d6
move.w (sp)+,d5
add.w d3,(a2)+
dbra d0,1$
move.l (sp)+,d3
rts
dc.l 1
GetS_1 add.w #$100,d6
moveq #0,d1
move.l d6,-(sp)
move.l d2,d6
cmp.l ci_endoffset(a5),d6
bls.s aag_ok
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s aag_noloop
sub.l ci_restartoffset(a5),d6
aag_ok move.b 0(a6,d6.l),d1
add.w d1,d1
move.w 0(a3,d1.w),d1
;move.w d1,ci_prevsample(a5)
aag_noloop move.l (sp)+,d6
rts
dc.l 1
GetS_1_16 add.w #$100,d6
moveq #0,d1
move.l d6,-(sp)
move.l d2,d6
cmp.l ci_endoffset(a5),d6
bls.s aag16_ok
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s aag16_noloop
sub.l ci_restartoffset(a5),d6
aag16_ok add.l d6,d6
move.w 0(a6,d6.l),d1
asr.w d7,d1
;move.w d1,ci_prevsample(a5)
aag16_noloop move.l (sp)+,d6
rts
dc.l -1
GetS_1b add.w #$100,d6
moveq #0,d1
move.l d6,-(sp)
move.l d2,d6
cmp.l ci_endoffset(a5),d6
bge.s aag_ok
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s aag_noloop
add.l ci_restartoffset(a5),d6
bra.s aag_ok
dc.l -1
GetS_1_16b add.w #$100,d6
moveq #0,d1
move.l d6,-(sp)
move.l d2,d6
cmp.l ci_endoffset(a5),d6
bge.s aag16_ok
btst #CHFLAGB_LOOP,ci_flags(a5)
beq.s aag16_noloop
add.l ci_restartoffset(a5),d6
bra.s aag16_ok
; -------------------------------------------------------------------
; Mixing routines: Stereo, 8/16-bit, forwards/backwards, smooth
; -------------------------------------------------------------------
sMIX_stereo8l movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/a4,-(sp)
bsr.w GetCurrS_8
move.w d1,ci_currsample(a5)
lea GetNextSample(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d3/d5/a4
rts
1$ movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1(pc),a4
bsr.w sMIX_avgleft
movem.l (sp)+,a1/a4
rts
sMIXb_stereo8l movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/a4,-(sp)
bsr.w GetCurrS_8
move.w d1,ci_currsample(a5)
lea GetNextSampleB(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d3/d5/a4
rts
1$ movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1b(pc),a4
bsr.w sMIX_avgleft
movem.l (sp)+,a1/a4
rts
sMIX_stereo8r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
movea.l ci_voltable_r(a5),a3
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/a4,-(sp)
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
bsr.w GetCurrS_8
move.w d1,ci_currsample_r(a5)
lea GetNextSample(pc),a4
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/a4
rts
1$ movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1(pc),a4
bsr.w sMIX_avgright
movem.l (sp)+,a1/a4
rts
sMIXb_stereo8r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
movea.l ci_voltable_r(a5),a3
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/a4,-(sp)
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
bsr.w GetCurrS_8
move.w d1,ci_currsample_r(a5)
lea GetNextSampleB(pc),a4
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/a4
rts
1$ movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1b(pc),a4
bsr.w sMIX_avgright
movem.l (sp)+,a1/a4
rts
sMIX_stereo8 movea.l ci_voltable_l(a5),a3
bra.s sMIX_st8
sMIX_stereo8c movea.l ci_voltable_l(a5),a3
move.l a3,ci_voltable_r(a5)
sMIX_st8 movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/a4,-(sp)
movem.l d0/d2/d4/a2,-(sp)
bsr.w GetCurrS_8
move.w d1,ci_currsample(a5)
lea GetNextSample(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d0/d2/d4/a2
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movea.l ci_voltable_r(a5),a3
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
bsr.w GetCurrS_8
move.w d1,ci_currsample_r(a5)
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/a4
rts
1$ movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1(pc),a4
movem.l d0/d2/d4/a2,-(sp)
bsr. sMIX_avgleft
movem.l (sp)+,d0/d2/d4/a2
movea.l ci_voltable_r(a5),a3
bsr.w sMIX_avgright
movem.l (sp)+,a1/a4
rts
sMIXb_stereo8 movea.l ci_voltable_l(a5),a3
bra.s sMIXb_st8
sMIXb_stereo8c movea.l ci_voltable_l(a5),a3
move.l a3,ci_voltable_r(a5)
sMIXb_st8 movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/a4,-(sp)
movem.l d0/d2/d4/a2,-(sp)
bsr.w GetCurrS_8
move.w d1,ci_currsample(a5)
lea GetNextSampleB(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d0/d2/d4/a2
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movea.l ci_voltable_r(a5),a3
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
bsr.w GetCurrS_8
move.w d1,ci_currsample_r(a5)
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/a4
rts
1$ movem.l a1/a4,-(sp)
lea GetCurrS_8(pc),a1
lea GetS_1b(pc),a4
movem.l d0/d2/d4/a2,-(sp)
bsr. sMIX_avgleft
movem.l (sp)+,d0/d2/d4/a2
movea.l ci_voltable_r(a5),a3
bsr.w sMIX_avgright
movem.l (sp)+,a1/a4
rts
sMIX_stereo16l movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/d7/a4,-(sp)
move.w ci_volshift_l(a5),d7
bsr.w GetCurrS_16
move.w d1,ci_currsample(a5)
lea GetNextSample_16(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d3/d5/d7/a4
rts
1$ movem.l a1/a4/d7,-(sp)
move.w ci_volshift_l(a5),d7
lea GetCurrS_16(pc),a1
lea GetS_1_16(pc),a4
bsr.w sMIX_avgleft
movem.l (sp)+,a1/a4/d7
rts
sMIXb_stereo16l movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/d7/a4,-(sp)
move.w ci_volshift_l(a5),d7
bsr.w GetCurrS_16
move.w d1,ci_currsample(a5)
lea GetNextSample_16B(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d3/d5/d7/a4
rts
1$ movem.l a1/a4/d7,-(sp)
move.w ci_volshift_l(a5),d7
lea GetCurrS_16(pc),a1
lea GetS_1_16b(pc),a4
bsr.w sMIX_avgleft
movem.l (sp)+,a1/a4/d7
rts
sMIX_stereo16r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/d7/a4,-(sp)
move.w ci_volshift_r(a5),d7
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
bsr.w GetCurrS_16
move.w d1,ci_currsample_r(a5)
lea GetNextSample_16(pc),a4
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/d7/a4
rts
1$ movem.l a1/a4/d7,-(sp)
move.w ci_volshift_r(a5),d7
lea GetCurrS_16(pc),a1
lea GetS_1_16(pc),a4
bsr.w sMIX_avgright
movem.l (sp)+,a1/a4/d7
rts
sMIXb_stereo16r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/d7/a4,-(sp)
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
move.w ci_volshift_r(a5),d7
bsr.w GetCurrS_16
move.w d1,ci_currsample_r(a5)
lea GetNextSample_16B(pc),a4
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/d7/a4
rts
1$ movem.l d7/a1/a4,-(sp)
move.w ci_volshift_r(a5),d7
lea GetCurrS_16(pc),a1
lea GetS_1_16b(pc),a4
bsr.w sMIX_avgright
movem.l (sp)+,d7/a1/a4
rts
sMIX_stereo16c move.w ci_volshift_l(a5),ci_volshift_r(a5)
sMIX_stereo16 movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/d7/a4,-(sp)
movem.l d0/d2/d4/a2,-(sp)
move.w ci_volshift_l(a5),d7
bsr.w GetCurrS_16
move.w d1,ci_currsample(a5)
lea GetNextSample_16(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d0/d2/d4/a2
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
move.w ci_volshift_r(a5),d7
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
bsr.w GetCurrS_16
move.w d1,ci_currsample_r(a5)
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/d7/a4
rts
1$ movem.l d7/a1/a4,-(sp)
lea GetCurrS_16(pc),a1
lea GetS_1_16(pc),a4
movem.l d0/d2/d4/a2,-(sp)
move.w ci_volshift_l(a5),d7
bsr. sMIX_avgleft
movem.l (sp)+,d0/d2/d4/a2
move.w ci_volshift_r(a5),d7
bsr.w sMIX_avgright
movem.l (sp)+,d7/a1/a4
rts
sMIXb_stereo16c move.w ci_volshift_l(a5),ci_volshift_r(a5)
sMIXb_stereo16 movea.l ci_sample_start(a5),a6
subq.w #1,d0
tst.w d5
bne.s 1$
movem.l d3/d5/d7/a4,-(sp)
movem.l d0/d2/d4/a2,-(sp)
move.w ci_volshift_l(a5),d7
bsr.w GetCurrS_16
move.w d1,ci_currsample(a5)
lea GetNextSample_16B(pc),a4
bsr.w sMIX_leftloop
movem.l (sp)+,d0/d2/d4/a2
bset #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
move.w ci_volshift_r(a5),d7
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
bsr.w GetCurrS_16
move.w d1,ci_currsample_r(a5)
bsr.w sMIX_rightloop
bclr #CHFLAGB_MIXING_RIGHT,ci_flags(a5)
movem.l (sp)+,d3/d5/d7/a4
rts
1$ movem.l d7/a1/a4,-(sp)
lea GetCurrS_16(pc),a1
lea GetS_1_16b(pc),a4
movem.l d0/d2/d4/a2,-(sp)
move.w ci_volshift_l(a5),d7
bsr. sMIX_avgleft
movem.l (sp)+,d0/d2/d4/a2
move.w ci_volshift_r(a5),d7
bsr.w sMIX_avgright
movem.l (sp)+,d7/a1/a4
rts
sMIX_leftloop jsr (a4)
1$ move.w ci_currsample(a5),d1
ext.l d1
move.w ci_prevsample(a5),d5
ext.l d5
sub.l d1,d5
neg.l d5 ;f' at fract 0 (curr - prev)
move.w ci_nextsample(a5),d3
ext.l d3
sub.l d1,d3 ;f' at fract $FFFF (next - curr)
sub.l d5,d3 ;f'' during the curr. sample
lsr.l #2,d3
lsr.w #1,d4
muls d4,d3 ;get f'' at curr. fract
roxl.w #1,d4
swap d3 ;/ 0x10000
ext.l d3
asl.l #2,d3
add.l d5,d3 ;add initial f' at fract 0
lsr.l #2,d3
lsr.w #1,d4
muls d4,d3
roxl.w #1,d4
asl.l #3,d3
swap d3 ;/ 0x10000
move.w ci_prevsample(a5),d5
ext.l d5
add.l d5,d1
lsr.l #1,d1
add.w d3,d1 ;add to initial sample value
bvc.s 2$
move.w ci_currsample(a5),d1
2$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4 ;actually advance fraction
bcc.s 4$
jsr -4(a4) ;add (or subtract) one to offset
move.l ci_currsample(a5),ci_prevsample(a5)
jsr (a4)
4$ dbra d0,1$
rts
sMIX_rightloop jsr (a4)
1$ move.w ci_currsample_r(a5),d1
ext.l d1
move.w ci_prevsample_r(a5),d5
ext.l d5
sub.l d1,d5
neg.l d5 ;f' at fract 0 (curr - prev)
move.w ci_nextsample_r(a5),d3
ext.l d3
sub.l d1,d3 ;f' at fract $FFFF (next - curr)
sub.l d5,d3 ;f'' during the curr. sample
lsr.l #2,d3
lsr.w #1,d4
muls d4,d3 ;get f'' at curr. fract
roxl.w #1,d4
swap d3 ;/ 0x10000
ext.l d3
asl.l #2,d3
add.l d5,d3 ;add initial f' at fract 0
lsr.l #2,d3
lsr.w #1,d4
muls d4,d3
roxl.w #1,d4
asl.l #3,d3
swap d3 ;/ 0x10000
move.w ci_prevsample_r(a5),d5
ext.l d5
add.l d5,d1
lsr.l #1,d1
add.w d3,d1 ;add to initial sample value
bvc.s 2$
move.w ci_currsample(a5),d1
2$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;actually advance fraction
bcc.s 4$
jsr -4(a4) ;add (or subtract) one to offset
move.l ci_currsample_r(a5),ci_prevsample_r(a5)
jsr (a4)
4$ dbra d0,1$
rts
sMIX_avgleft move.l d3,-(sp)
1$ move.w d4,d3
not.w d3 ;what's left of current sample
jsr (a1)
lsr.w #1,d3
muls d1,d3
asr.l #7,d3 ;/ 256..
move.w d5,-(sp)
move.w d6,-(sp)
move.w d4,d6
not.w d6
lsr.w #8,d6 ;divisor
add.l -4(a4),d2 ;advance offset
subq.w #2,d5
bmi.s 2$ ;no full samples to skip
3$ jsr (a4)
add.l -4(a4),d2 ;advance offset
swap d1
asr.l #8,d1
add.l d1,d3
dbra d5,3$
2$ add.w (sp),d4 ;d6 = (sp) = advfract
bcc.s 4$
jsr (a4)
add.l -4(a4),d2 ;advance offset
swap d1
asr.l #8,d1
add.l d1,d3
4$ jsr 4(a4) ;get last (partial) sample
move.w d4,d5
lsr.w #8,d5
add.w d5,d6
move.w d4,d5
lsr.w #1,d5
muls d5,d1
asr.l #7,d1
add.l d1,d3
divs d6,d3 ;divide to get average
move.w (sp)+,d6
move.w (sp)+,d5
add.w d3,(a2)
addq.l #4,a2
dbra d0,1$
move.l (sp)+,d3
rts
sMIX_avgright move.l d3,-(sp)
1$ move.w d4,d3
not.w d3 ;what's left of current sample
jsr (a1)
lsr.w #1,d3
muls d1,d3
asr.l #7,d3 ;/ 256..
move.w d5,-(sp)
move.w d6,-(sp)
move.w d4,d6
not.w d6
lsr.w #8,d6 ;divisor
add.l -4(a4),d2 ;advance offset
subq.w #2,d5
bmi.s 2$ ;no full samples to skip
3$ jsr (a4)
add.l -4(a4),d2 ;advance offset
swap d1
asr.l #8,d1
add.l d1,d3
dbra d5,3$
2$ add.w (sp),d4 ;d6 = (sp) = advfract
bcc.s 4$
jsr (a4)
add.l -4(a4),d2 ;advance offset
swap d1
asr.l #8,d1
add.l d1,d3
4$ jsr 4(a4) ;get last (partial) sample
move.w d4,d5
lsr.w #8,d5
add.w d5,d6
move.w d4,d5
lsr.w #1,d5
muls d5,d1
asr.l #7,d1
add.l d1,d3
divs d6,d3 ;divide to get average
move.w (sp)+,d6
move.w (sp)+,d5
addq.l #2,a2
add.w d3,(a2)+
dbra d0,1$
move.l (sp)+,d3
rts
ENDC
IFNE SUPPORT_000
; -------------------------------------------------------------------
; Mixing routine: Mono, 16-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_mono16 movea.l ci_sample_start(a5),a6
move.l d3,a3
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2 ;temporarily mul by 2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1
asr.w d3,d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
addq.l #2,d2
5$ move.w 0(a6,d2.l),d1
asr.w d3,d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
lsr.l #1,d2
move.l a3,d3
rts
8$ addq.l #2,d2
dbra d0,4$
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Mono, 16-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_mono16 movea.l ci_sample_start(a5),a6
move.l d3,a3
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset -= advance
2$ move.l d2,d1
add.l d1,d1
move.w 0(a6,d1.l),d1
asr.w d3,d1
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2 ;temporarily mul by 2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1
asr.w d3,d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #2,d2
5$ move.w 0(a6,d2.l),d1
asr.w d3,d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
asr.l #1,d2
move.l a3,d3
rts
8$ subq.l #2,d2
dbra d0,4$
asr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Mono, 8-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_mono8 movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a3,d1.w),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a3,d1.w),d1
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a3,d1.w),d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a3,d1.w),d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ addq.l #1,d2
dbra d0,4$
rts
; -------------------------------------------------------------------
; Mixing routine: Mono, 8-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_mono8 movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a3,d1.w),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a3,d1.w),d1
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a3,d1.w),d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a3,d1.w),d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ subq.l #1,d2
dbra d0,4$
rts
ENDC
IFNE SUPPORT_020
; -------------------------------------------------------------------
; Mixing routine: Mono, 16-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_mono16_020 movea.l ci_sample_start(a5),a6
move.l d3,a3
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ lea 0(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w (a0)+,d1
asr.w d3,d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.w (a0)+,d1
asr.w d3,d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
subq.l #1,d2
lsr.l #1,d2
move.l a3,d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Mono, 16-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_mono16_020 movea.l ci_sample_start(a5),a6
move.l d3,a3
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset -= advance
2$ move.w 0(a6,d2.l*2),d1
asr.w d3,d1
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
move.l a3,d3
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l*2),d1
asr.w d3,d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ move.w 0(a6,d2.l*2),d1
asr.w d3,d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
move.l a3,d3
rts
8$ subq.l #1,d2
dbra d0,4$
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Mono, 8bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_mono8_020 movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
swap d3 ;scratch the upper word of D3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
swap d3
rts
3$ movea.l a6,a0
add.l d2,a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b (a0)+,d3
move.w 0(a3,d3.w*2),d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.b (a0)+,d3
move.w 0(a3,d3.w*2),d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
subq.l #1,d2
swap d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Mono, 8-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_mono8_020 movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a3
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
swap d3
rts
3$ lea 1(a6,d2.l),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b -(a0),d3
move.w 0(a3,d3.w*2),d1
6$ add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
; subq.l #1,d2
5$ move.b -(a0),d3
move.w 0(a3,d3.w*2),d1
7$ add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
swap d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
subq.l #1,d2
swap d3
rts
ENDC
IFNE SUPPORT_000
; -------------------------------------------------------------------
; Mixing routine: Stereo generic, 8-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo8 movea.l ci_sample_start(a5),a6
movem.l ci_voltable_l(a5),a0/a3
swap d7
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d7 ;left volume
add.w d7,(a2)+
move.w 0(a3,d1.w),d7
add.w d7,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d7 ;left volume
add.w d7,(a2)+
move.w 0(a3,d1.w),d7
add.w d7,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
swap d7
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d7 ;left volume
move.w 0(a3,d1.w),d1
6$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d7
move.w 0(a3,d1.w),d1
7$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
swap d7
rts
8$ addq.l #1,d2
dbra d0,4$
swap d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 8-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo8l movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
addx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
6$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
7$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ addq.l #1,d2
dbra d0,4$
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 8-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo8r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
movea.l ci_voltable_r(a5),a0
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ addq.l #1,d2
dbra d0,4$
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 8-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo8c movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ addq.l #1,d2
dbra d0,4$
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 8-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo8s movem.l d7/a4,-(sp)
move.l ci_sample_start(a5),a0
move.l a0,a6
adda.l ci_rightch_offs(a5),a6
movem.l ci_voltable_l(a5),a3/a4
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a0,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
add.w d1,(a2)+
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
add.w d7,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a0,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
add.w d1,(a2)+
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
add.w d7,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
movem.l (sp)+,d7/a4
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a0,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
6$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ moveq #0,d1
move.b 0(a0,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
7$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
movem.l (sp)+,d7/a4
rts
8$ addq.l #1,d2
dbra d0,4$
movem.l (sp)+,d7/a4
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo, 8-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo8 movea.l ci_sample_start(a5),a6
movem.l ci_voltable_l(a5),a0/a3
move.w d7,-(sp)
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d7 ;left volume
add.w d7,(a2)+
move.w 0(a3,d1.w),d7
add.w d7,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d7 ;left volume
add.w d7,(a2)+
move.w 0(a3,d1.w),d7
add.w d7,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
move.w (sp)+,d7
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d7 ;left volume
move.w 0(a3,d1.w),d1
6$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d7
move.w 0(a3,d1.w),d1
7$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
move.w (sp)+,d7
rts
8$ subq.l #1,d2
dbra d0,4$
move.w (sp)+,d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 8-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo8l movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
subx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
6$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
7$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ subq.l #1,d2
dbra d0,4$
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 8-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo8r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
movea.l ci_voltable_r(a5),a0
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ subq.l #1,d2
dbra d0,4$
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 8-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo8c movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1 ;left volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ moveq #0,d1
move.b 0(a6,d2.l),d1
add.w d1,d1
move.w 0(a0,d1.w),d1
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
rts
8$ subq.l #1,d2
dbra d0,4$
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 8-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo8s movem.l d7/a4,-(sp)
movea.l ci_sample_start(a5),a0
move.l a0,a6
adda.l ci_rightch_offs(a5),a6
movem.l ci_voltable_l(a5),a3/a4
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ moveq #0,d1
move.b 0(a0,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
add.w d1,(a2)+
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
add.w d7,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
add.w d1,(a2)+
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
add.w d7,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
movem.l (sp)+,d7/a4
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ moveq #0,d1
move.b 0(a0,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
6$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ moveq #0,d1
move.b 0(a0,d2.l),d1 ;sample (left)
add.w d1,d1
move.w 0(a3,d1.w),d1 ;left volume
moveq #0,d7
move.b 0(a6,d2.l),d7 ;sample (right)
add.w d7,d7
move.w 0(a4,d7.w),d7
7$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
movem.l (sp)+,d7/a4
rts
8$ subq.l #1,d2
dbra d0,4$
movem.l (sp)+,d7/a4
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 16-bit, forwards, 68000
; -------------------------------------------------------------------
; (No alternative version here... out of registers.)
MIX_stereo16s move.l ci_sample_start(a5),a0
movea.l a0,a6
adda.l ci_rightch_offs(a5),a6
swap d3
swap d7
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,a3
add.l a3,a3 ;offset * 2
move.w 0(a0,a3.l),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,a3.l),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.l d2,a3
add.l a3,a3 ;offset * 2
move.w 0(a0,a3.l),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,a3.l),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
swap d3
swap d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 16-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo16l movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcc.s 7$
addq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
lsr.l #1,d2
move.l a3,d3
rts
8$ addq.l #2,d2
dbra d0,4$
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 16-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo16r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_r(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
addq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
lsr.l #1,d2
move.l a3,d3
rts
8$ addq.l #2,d2
dbra d0,4$
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 16-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo16c movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
addq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
lsr.l #1,d2
move.l a3,d3
rts
8$ addq.l #2,d2
dbra d0,4$
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo generic, 16-bit, forwards, 68000
; -------------------------------------------------------------------
MIX_stereo16 movea.l ci_sample_start(a5),a6
swap d3 ;upper words are free for scratch
swap d7 ;use
move.w d6,a3
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4
addx.l d5,d2
dbra d0,1$
move.l a3,d6
swap d3
swap d7
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
move.w d1,d6
asr.w d3,d1
asr.w d7,d6
6$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcc.s 7$
addq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
asr.w d7,d6
7$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
lsr.l #1,d2
move.l a3,d6
swap d3
swap d7
rts
8$ addq.l #2,d2
dbra d0,4$
lsr.l #1,d2
move.l a3,d6
swap d3
swap d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 16-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo16s move.l ci_sample_start(a5),a0
movea.l a0,a6
adda.l ci_rightch_offs(a5),a6
swap d3
swap d7
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,a3
add.l a3,a3 ;offset * 2
move.w 0(a0,a3.l),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,a3.l),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.l d2,a3
add.l a3,a3 ;offset * 2
move.w 0(a0,a3.l),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,a3.l),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
swap d3
swap d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 16-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo16l movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcc.s 7$
subq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
asr.l #1,d2
move.l a3,d3
rts
8$ subq.l #2,d2
dbra d0,4$
asr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 16-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo16r movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_r(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
subq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
asr.l #1,d2
move.l a3,d3
rts
8$ subq.l #2,d2
dbra d0,4$
asr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 16-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo16c movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
subq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
asr.l #1,d2
move.l a3,d3
rts
8$ subq.l #2,d2
dbra d0,4$
asr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo generic, 16-bit, backwards, 68000
; -------------------------------------------------------------------
MIXb_stereo16 movea.l ci_sample_start(a5),a6
swap d3 ;upper words are free for scratch
swap d7 ;use
move.w d6,a3
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.l d2,d1
add.l d1,d1 ;offset * 2
move.w 0(a6,d1.l),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4
subx.l d5,d2
dbra d0,1$
move.l a3,d6
swap d3
swap d7
rts
3$ add.l d2,d2
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l),d1 ;sample
move.w d1,d6
asr.w d3,d1
asr.w d7,d6
6$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcc.s 7$
subq.l #2,d2
5$ move.w 0(a6,d2.l),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
asr.w d7,d6
7$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
asr.l #1,d2
move.l a3,d6
swap d3
swap d7
rts
8$ subq.l #2,d2
dbra d0,4$
asr.l #1,d2
move.l a3,d6
swap d3
swap d7
rts
ENDC
IFNE SUPPORT_020
; -------------------------------------------------------------------
; Mixing routine: Stereo generic, 8-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo8_020 movea.l ci_sample_start(a5),a6
movem.l ci_voltable_l(a5),a0/a3
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
add.w d1,(a2)+
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
add.w d1,(a2)+
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
swap d3
rts
3$ swap d7
move.l a4,-(sp)
movea.l a6,a4
add.l d2,a4
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b (a4)+,d3
move.w 0(a0,d3.w*2),d7 ;left volume
move.w 0(a3,d3.w*2),d1
6$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.b (a4)+,d3
move.w 0(a0,d3.w*2),d7
move.w 0(a3,d3.w*2),d1
7$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a4
move.l a4,d2
subq.l #1,d2
swap d7
swap d3
move.l (sp)+,a4
rts
8$ dbra d0,4$
suba.l a6,a4
move.l a4,d2
swap d7
swap d3
move.l (sp)+,a4
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 8-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo8l_020
movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
addx.l d5,d2
dbra d0,1$
swap d3
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1 ;left volume
6$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
7$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcs.s 8$
dbra d0,6$
swap d3
rts
8$ addq.l #1,d2
dbra d0,4$
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 8-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo8r_020
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
movea.l ci_voltable_r(a5),a0
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
swap d3
rts
3$ movea.l a6,a3
add.l d2,a3
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b (a3)+,d3
move.w 0(a0,d3.w*2),d1 ;left volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.b (a3)+,d3
move.w 0(a0,d3.w*2),d1
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a3
move.l a3,d2
subq.l #1,d2
swap d3
rts
8$ dbra d0,4$
suba.l a6,a3
move.l a3,d2
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 8-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo8c_020
movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
swap d3
rts
3$ movea.l a6,a3
add.l d2,a3
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b (a3)+,d3
move.w 0(a0,d3.w*2),d1 ;left volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.b (a3)+,d3
move.w 0(a0,d3.w*2),d1
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a3
move.l a3,d2
subq.l #1,d2
swap d3
rts
8$ dbra d0,4$
suba.l a6,a3
move.l a3,d2
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 8-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo8s_020
move.l a4,-(sp)
move.l ci_sample_start(a5),a0
move.l a0,a6
adda.l ci_rightch_offs(a5),a6
movem.l ci_voltable_l(a5),a3/a4
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
add.w d1,(a2)+
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
add.w d1,(a2)+
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4
addx.l d5,d2
dbra d0,1$
swap d3
move.l (sp)+,a4
rts
3$ swap d7
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d7
6$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcc.s 7$
addq.l #1,d2
5$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d7
7$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
swap d3
swap d7
move.l (sp)+,a4
rts
8$ addq.l #1,d2
dbra d0,4$
swap d3
swap d7
move.l (sp)+,a4
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo generic, 8-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo8_020
movea.l ci_sample_start(a5),a6
movem.l ci_voltable_l(a5),a0/a3
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
add.w d1,(a2)+
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
add.w d1,(a2)+
move.w 0(a3,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
swap d3
rts
3$ swap d7
move.l a4,-(sp)
lea 1(a6,d2.l),a4
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b -(a4),d3
move.w 0(a0,d3.w*2),d7 ;left volume
move.w 0(a3,d3.w*2),d1
6$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.b -(a4),d3
move.w 0(a0,d3.w*2),d7
move.w 0(a3,d3.w*2),d1
7$ add.w d7,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a4
move.l a4,d2
move.l (sp)+,a4
swap d7
swap d3
rts
8$ dbra d0,4$
suba.l a6,a4
move.l a4,d2
subq.l #1,d2
move.l (sp)+,a4
swap d7
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 8-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo8l_020
movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ moveq #0,d1
move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
subx.l d5,d2
dbra d0,1$
swap d3
rts
3$ lea 1(a6,d2.l),a3
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b -(a3),d3
move.w 0(a0,d3.w*2),d1 ;left volume
6$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcc.s 7$
5$ move.b -(a3),d3
move.w 0(a0,d3.w*2),d1
7$ add.w d1,(a2)
addq.l #4,a2
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a3
move.l a3,d2
swap d3
rts
8$ dbra d0,4$
suba.l a6,a3
move.l a3,d2
subq.l #1,d2
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 8-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo8r_020
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
movea.l ci_voltable_r(a5),a0
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
swap d3
rts
3$ lea 1(a6,d2.l),a3
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b -(a3),d3
move.w 0(a0,d3.w*2),d1 ;left volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.b -(a3),d3
move.w 0(a0,d3.w*2),d1
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a3
move.l a3,d2
swap d3
rts
8$ dbra d0,4$
suba.l a6,a3
move.l a3,d2
subq.l #1,d2
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 8-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo8c_020
movea.l ci_sample_start(a5),a6
movea.l ci_voltable_l(a5),a0
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a6,d2.l),d3 ;sample
move.w 0(a0,d3.w*2),d1 ;left volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.b 0(a6,d2.l),d3
move.w 0(a0,d3.w*2),d1
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
swap d3
rts
3$ lea 1(a6,d2.l),a3
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b -(a3),d3
move.w 0(a0,d3.w*2),d1 ;left volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcc.s 7$
5$ move.b -(a3),d3
move.w 0(a0,d3.w*2),d1
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
suba.l a6,a3
move.l a3,d2
swap d3
rts
8$ dbra d0,4$
suba.l a6,a3
move.l a3,d2
subq.l #1,d2
swap d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 8-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo8s_020
move.l a4,-(sp)
move.l ci_sample_start(a5),a0
move.l a0,a6
adda.l ci_rightch_offs(a5),a6
movem.l ci_voltable_l(a5),a3/a4
swap d3
tst.w d5
beq.s 3$ ;advance zero
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
add.w d1,(a2)+
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
add.w d1,(a2)+
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d1
add.w d1,(a2)+
add.w d6,d4
subx.l d5,d2
dbra d0,1$
swap d3
move.l (sp)+,a4
rts
3$ swap d7
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d7
6$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcc.s 7$
subq.l #1,d2
5$ move.b 0(a0,d2.l),d3 ;sample (left)
move.w 0(a3,d3.w*2),d1 ;left volume
move.b 0(a6,d2.l),d3 ;sample (right)
move.w 0(a4,d3.w*2),d7
7$ add.w d1,(a2)+
add.w d7,(a2)+
add.w d6,d4
bcs.s 8$
dbra d0,6$
swap d3
swap d7
move.l (sp)+,a4
rts
8$ subq.l #1,d2
dbra d0,4$
swap d3
swap d7
move.l (sp)+,a4
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 16-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo16s_020
move.l ci_sample_start(a5),a0
movea.l a0,a6
adda.l ci_rightch_offs(a5),a6
swap d3
swap d7
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a0,d2.l*2),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,d2.l*2),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.w 0(a0,d2.l*2),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,d2.l*2),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
swap d3
swap d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 16-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo16l_020
movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ lea 0(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w (a0)+,d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcc.s 7$
addq.l #1,d2
5$ move.w (a0)+,d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
subq.l #2,d2
lsr.l #1,d2
move.l a3,d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 16-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo16r_020
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_r(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ lea 0(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w (a0)+,d1 ;sample
asr.w d3,d1 ;scale volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
5$ move.w (a0)+,d1 ;sample
asr.w d3,d1 ;scale volume
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
subq.l #2,d2
lsr.l #1,d2
move.l a3,d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 16-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo16c_020
movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ lea 0(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w (a0)+,d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
5$ move.w (a0)+,d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
subq.l #2,d2
lsr.l #1,d2
move.l a3,d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo generic, 16-bit, forwards, 68020+
; -------------------------------------------------------------------
MIX_stereo16_020
movea.l ci_sample_start(a5),a6
swap d3 ;upper words are free for scratch
swap d7 ;use
move.w d6,a3
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
addx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4
addx.l d5,d2
dbra d0,1$
move.l a3,d6
swap d3
swap d7
rts
3$ lea 0(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w (a0)+,d1 ;sample
move.w d1,d6
asr.w d3,d1
asr.w d7,d6
6$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcc.s 7$
5$ move.w (a0)+,d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
asr.w d7,d6
7$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
subq.l #2,d2
lsr.l #1,d2
move.l a3,d6
swap d3
swap d7
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d6
swap d3
swap d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo two-channel, 16-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo16s_020
move.l ci_sample_start(a5),a0
movea.l a0,a6
adda.l ci_rightch_offs(a5),a6
swap d3
swap d7
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a0,d2.l*2),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,d2.l*2),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.w 0(a0,d2.l*2),d1 ;sample (L)
asr.w d3,d1 ;scale vol (L)
add.w d1,(a2)+
move.w 0(a6,d2.l*2),d1
asr.w d7,d1 ;scale vol (R)
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
swap d3
swap d7
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo left ch, 16-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo16l_020
movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ lea 2(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w -(a0),d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcc.s 7$
5$ move.w -(a0),d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
addq.l #2,a2
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
subq.l #2,d2
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo right ch, 16-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo16r_020
movea.l ci_sample_start(a5),a6
adda.l ci_rightch_offs(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_r(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ lea 2(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w -(a0),d1 ;sample
asr.w d3,d1 ;scale volume
6$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
5$ move.w -(a0),d1 ;sample
asr.w d3,d1 ;scale volume
7$ addq.l #2,a2
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
subq.l #2,d2
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo centered, 16-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo16c_020
movea.l ci_sample_start(a5),a6
move.l d3,a3 ;store
move.w ci_volshift_l(a5),d3
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
dbra d0,1$
move.l a3,d3
rts
3$ lea 2(a6,d2.l*2),a0
lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w -(a0),d1 ;sample
asr.w d3,d1 ;scale volume
6$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcc.s 7$
5$ move.w -(a0),d1 ;sample
asr.w d3,d1 ;scale volume
7$ add.w d1,(a2)+
add.w d1,(a2)+
add.w d6,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
suba.l a6,a0
move.l a0,d2
lsr.l #1,d2
move.l a3,d3
rts
8$ dbra d0,4$
suba.l a6,a0
move.l a0,d2
subq.l #2,d2
lsr.l #1,d2
move.l a3,d3
rts
; -------------------------------------------------------------------
; Mixing routine: Stereo generic, 16-bit, backwards, 68020+
; -------------------------------------------------------------------
MIXb_stereo16_020
movea.l ci_sample_start(a5),a6
swap d3 ;upper words are free for scratch
swap d7 ;use
move.w d6,a3
move.w ci_volshift_l(a5),d3
move.w ci_volshift_r(a5),d7
tst.w d5
beq.s 3$
lsr.w #1,d0
bcs.s 2$
subq.w #1,d0
1$ move.w 0(a6,d2.l*2),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
subx.l d5,d2 ;offset += advance
2$ move.w 0(a6,d2.l*2),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
add.w d1,(a2)+
asr.w d7,d6
add.w d6,(a2)+
add.w a3,d4
subx.l d5,d2
dbra d0,1$
move.l a3,d6
swap d3
swap d7
rts
3$ lsr.w #1,d0
bcs.s 5$
subq.w #1,d0
4$ move.w 0(a6,d2.l*2),d1 ;sample
move.w d1,d6
asr.w d3,d1
asr.w d7,d6
6$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcc.s 7$
subq.l #1,d2
5$ move.w 0(a6,d2.l*2),d1 ;sample
move.w d1,d6
asr.w d3,d1 ;scale volume
asr.w d7,d6
7$ add.w d1,(a2)+
add.w d6,(a2)+
add.w a3,d4 ;fraction += advfract
bcs.s 8$
dbra d0,6$
move.l a3,d6
swap d3
swap d7
rts
8$ subq.l #1,d2
dbra d0,4$
move.l a3,d6
swap d3
swap d7
rts
ENDC
; -------------------------------------------------------------------
; Interface routines called by the player routine.
; -------------------------------------------------------------------
XDEF _MixSetTrkPeriod
; D1 = period, D7 = track number, A5 = track data
_MixSetTrkPeriod:
cmp.w m_channels(pc),d7
bhs.s mstp_exit
movea.l trk_cinfo(a5),a0
moveq #0,d0
move.w d1,d0
beq.s _ChOff_mix
move.w m_actualrate(pc),d1
; CalcAdv ;d0.l = note_freq, d1.w = actualrate_hz
divu d1,d0
move.w d0,ci_advance+2(a0) ;set advance
clr.w d0
divu d1,d0
move.w d0,ci_advfract+2(a0)
beq.s mstp_advfract0
mstp_exit rts
; advfract == 0, if also advance == 0, stop sound (would cause
; division by zero).
mstp_advfract0 tst.w ci_advance+2(a0)
beq.s _ChOff_mix
rts
; Prepare for a synthsound. (The next MixSetSynthWF will start
; playing from the beginning of the wf instead of waiting for
; the previous wf to finish.)
XDEF _MixPrepSynth
_MixPrepSynth
cmp.w m_channels(pc),d7
bhs.s mps_exit
movea.l trk_cinfo(a5),a0
bset #CHFLAGB_STARTSYN,ci_flags(a0)
mps_exit rts
; Channel off. (Just set the MUTED flag.)
; (Note: do not trash anything without modifying _ChannelOff!)
XDEF _ChOff_mix
_ChOff_mix
cmp.w m_channels(pc),d7
bhs.s comix_exit
movea.l trk_cinfo(a5),a0
bset #CHFLAGB_MUTED,ci_flags(a0)
comix_exit rts
; Set Synthsound waveform.
; A1 = Synth waveform, D7 = track, A5 = track data
XDEF _MixSetSynthWF
_MixSetSynthWF
cmp.w m_channels(pc),d7
bhs.s mssw_exit
movea.l trk_cinfo(a5),a0
moveq #0,d1
move.w (a1)+,d1 ;synthwf length
add.w d1,d1 ;* 2
move.w d1,ci_newendoffset+2(a0)
move.l a1,ci_newstart_addr(a0)
btst #CHFLAGB_STARTSYN,ci_flags(a0)
beq.s mssw_setloop
move.l a1,ci_sample_start(a0)
move.l d1,ci_endoffset(a0)
move.l d1,ci_restartoffset(a0)
clr.l ci_offset(a0)
mssw_setloop move.b #1<<CHFLAGB_LOOP,ci_flags(a0)
mssw_exit rts
; Set volume table and mixing routine
; D0 = volume (UBYTE), D7 = track, A5 = track data, A4 = song
XDEF _MixSetTrkVol
XREF _voltable,_chshift
mstv_exit rts
_MixSetTrkVol
cmp.w m_channels(pc),d7
bhs.s mstv_exit
movea.l trk_cinfo(a5),a0
; --- find correct handler
subq.b #1,d0
bpl.s mstv_non0
lea mixr_skip(pc),a1
bra.s mstv_set
mstv_non0 tst.b m_stereo
bne.s mstv_stereo
lea mixr_mono(pc),a1
bra.s mstv_set
mstv_stereo
IFNE OCTAMED_INTERN
lea msng_trkpan(a4),a1
ELSEIF
move.l msng_trkpan(a4),d1
beq.s mstv_nopanarray
move.l d1,a1
ENDC
move.b 0(a1,d7.w),d1 ;get pan
mstv_nopanarray cmp.b #-16,d1
bne.s mstv_noleftpan
lea mixr_stereol(pc),a1
bra.s mstv_set
mstv_noleftpan cmp.b #16,d1
bne.s mstv_norightpan
lea mixr_stereor(pc),a1
bra.s mstv_set
mstv_norightpan btst #CHFLAGB_STEREO,ci_flags(a0)
beq.s mstv_nostereos
lea mixr_stereos(pc),a1
bra.s mstv_set
mstv_nostereos tst.b d1
bne.s mstv_nocenter
lea mixr_stereoc(pc),a1
bra.s mstv_set
mstv_nocenter lea mixr_stereo(pc),a1
; --- handler found... set parameters
mstv_set btst #CHFLAGB_16BIT,ci_flags(a0)
bne.s mstv_set16
btst #CHFLAGB_BACKW,ci_flags(a0)
bne.s mstv_set8b
move.l 8(a1),ci_mixroutine(a0) ;set 8-bit routine
move.l 16(a1),ci_altmixroutine(a0) ;backwards
move.l (a1),a1
jmp (a1)
mstv_set8b move.l 16(a1),ci_mixroutine(a0) ;8-bit backwards
move.l 8(a1),ci_altmixroutine(a0) ;forwards
move.l (a1),a1
jmp (a1)
mstv_set16 btst #CHFLAGB_BACKW,ci_flags(a0)
bne.s mstv_set16b
move.l 12(a1),ci_mixroutine(a0) ;16-bit routine
move.l 20(a1),ci_altmixroutine(a0)
move.l 4(a1),a1
jmp (a1)
mstv_set16b move.l 20(a1),ci_mixroutine(a0) ;16-bit backwards
move.l 12(a1),ci_altmixroutine(a0)
move.l 4(a1),a1
jmp (a1)
; --- mono/stereo, volume zero
mstv_skip rts
; --- stereo 8-bit
mstv_stereo8 move.l d2,-(sp)
moveq #16,d2
sub.b d1,d2 ;16 - trkpan
ext.w d0
mulu d0,d2 ;* (vol - 1)
and.w #$FFE0,d2 :/ 32 * 256 * 2..
lsl.w #4,d2
move.l _voltable,a1
add.l a1,d2
move.l d2,ci_voltable_l(a0)
add.b #16,d1 ;16 + trkpan
ext.w d1
mulu d0,d1 ; * (vol - 1)
and.w #$FFE0,d1
lsl.w #4,d1
add.l a1,d1
move.l d1,ci_voltable_r(a0)
move.l (sp)+,d2
rts
; --- stereo 8-bit (panned to left) or mono 8-bit
mstv_stereo8l lsl.w #8,d0
move.l _voltable,a1
add.w d0,d0
adda.w d0,a1
move.l a1,ci_voltable_l(a0)
rts
; --- stereo 8-bit (panned to right)
mstv_stereo8r lsl.w #8,d0
move.l _voltable,a1
add.w d0,d0
adda.w d0,a1
move.l a1,ci_voltable_r(a0)
rts
; --- stereo 8-bit (panned to center)
mstv_stereo8c bclr #0,d0
lsl.w #8,d0
move.l _voltable,a1
adda.w d0,a1
move.l a1,ci_voltable_l(a0)
rts
; --- stereo 16-bit (panned to left) or mono 16-bit
mstv_stereo16l move.w _chshift,d1
ext.w d0
add.b volshifttbl(pc,d0.w),d1
move.w d1,ci_volshift_l(a0)
rts
; --- stereo 16-bit (panned to center)
mstv_stereo16c move.w _chshift,d1
ext.w d0
add.b volshifttbl(pc,d0.w),d1
addq.b #1,d1
move.w d1,ci_volshift_l(a0)
rts
; --- stereo 16-bit
mstv_stereo16 movem.l d2/d3,-(sp)
moveq #16,d2
sub.b d1,d2 ;16 - trkpan
ext.w d0
mulu d0,d2 ;* (vol - 1)
lsr.w #5,d2 ;/ 32
move.w _chshift,d3
move.b volshifttbl(pc,d2.w),d2
add.w d3,d2
move.w d2,ci_volshift_l(a0)
add.b #16,d1
ext.w d1
mulu d0,d1
lsr.w #5,d1
add.b volshifttbl(pc,d1.w),d3
move.w d3,ci_volshift_r(a0)
movem.l (sp)+,d2/d3
rts
; --- stereo 16-bit (panned to right)
mstv_stereo16r move.w _chshift,d1
ext.w d0
add.b volshifttbl(pc,d0.w),d1
move.w d1,ci_volshift_r(a0)
rts
; 16 bit volume shifting table
volshifttbl dc.b 6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
IFNE SUPPORT_000
mixr_skip dc.l mstv_skip,mstv_skip,Skip,Skip,Skipb,Skipb
mixr_mono dc.l mstv_stereo8l,mstv_stereo16l,MIX_mono8,MIX_mono16,MIXb_mono8,MIXb_mono16
mixr_stereo dc.l mstv_stereo8,mstv_stereo16,MIX_stereo8,MIX_stereo16,MIXb_stereo8,MIXb_stereo16
mixr_stereol dc.l mstv_stereo8l,mstv_stereo16l,MIX_stereo8l,MIX_stereo16l,MIXb_stereo8l,MIXb_stereo16l
mixr_stereor dc.l mstv_stereo8r,mstv_stereo16r,MIX_stereo8r,MIX_stereo16r,MIXb_stereo8r,MIXb_stereo16r
mixr_stereoc dc.l mstv_stereo8c,mstv_stereo16c,MIX_stereo8c,MIX_stereo16c,MIXb_stereo8c,MIXb_stereo16c
mixr_stereos dc.l mstv_stereo8,mstv_stereo16,MIX_stereo8s,MIX_stereo16s,MIXb_stereo8s,MIXb_stereo16s
ELSEIF
mixr_skip dc.l mstv_skip,mstv_skip,Skip_020,Skip_020,Skipb_020,Skipb_020
mixr_mono dc.l mstv_stereo8l,mstv_stereo16l,MIX_mono8_020,MIX_mono16_020,MIXb_mono8_020,MIXb_mono16_020
mixr_stereo dc.l mstv_stereo8,mstv_stereo16,MIX_stereo8_020,MIX_stereo16_020,MIXb_stereo8_020,MIXb_stereo16_020
mixr_stereol dc.l mstv_stereo8l,mstv_stereo16l,MIX_stereo8l_020,MIX_stereo16l_020,MIXb_stereo8l_020,MIXb_stereo16l_020
mixr_stereor dc.l mstv_stereo8r,mstv_stereo16r,MIX_stereo8r_020,MIX_stereo16r_020,MIXb_stereo8r_020,MIXb_stereo16r_020
mixr_stereoc dc.l mstv_stereo8c,mstv_stereo16c,MIX_stereo8c_020,MIX_stereo16c_020,MIXb_stereo8c_020,MIXb_stereo16c_020
mixr_stereos dc.l mstv_stereo8,mstv_stereo16,MIX_stereo8s_020,MIX_stereo16s_020,MIXb_stereo8s_020,MIXb_stereo16s_020
ENDC
IFNE SUPPORT_000&SUPPORT_020
mixr_020 dc.l Skip_020,Skip_020,Skipb_020,Skipb_020
dc.l MIX_mono8_020,MIX_mono16_020,MIXb_mono8_020,MIXb_mono16_020
dc.l MIX_stereo8_020,MIX_stereo16_020,MIXb_stereo8_020,MIXb_stereo16_020
dc.l MIX_stereo8l_020,MIX_stereo16l_020,MIXb_stereo8l_020,MIXb_stereo16l_020
dc.l MIX_stereo8r_020,MIX_stereo16r_020,MIXb_stereo8r_020,MIXb_stereo16r_020
dc.l MIX_stereo8c_020,MIX_stereo16c_020,MIXb_stereo8c_020,MIXb_stereo16c_020
dc.l MIX_stereo8s_020,MIX_stereo16s_020,MIXb_stereo8s_020,MIXb_stereo16s_020
ENDC
IFNE SUPPORT_SMOOTH
mixs dc.l sMIX_mono8,sMIX_mono16,sMIXb_mono8,sMIXb_mono16
dc.l sMIX_stereo8,sMIX_stereo16,sMIXb_stereo8,sMIXb_stereo16
dc.l sMIX_stereo8l,sMIX_stereo16l,sMIXb_stereo8l,sMIXb_stereo16l
dc.l sMIX_stereo8r,sMIX_stereo16r,sMIXb_stereo8r,sMIXb_stereo16r
dc.l sMIX_stereo8c,sMIX_stereo16c,sMIXb_stereo8c,sMIXb_stereo16c
dc.l sMIX_stereo8,sMIX_stereo16,sMIXb_stereo8,sMIXb_stereo16
ENDC
XREF _freq_tables
IFNE SUPPORT_SMOOTH
; Set smoothing routines
; smoothing, D0 = 0 or 1 for off or on (no other values accepted!)
XDEF _MixSmooth
_MixSmooth cmp.b m_smoothing(pc),d0
bne.s 1$
rts
1$ move.b d0,m_smoothing
lea mixs(pc),a0
lea mixr_mono(pc),a1
; swap mixing function pointers
moveq #5,d0
2$ addq.l #8,a1
move.l (a0),d1
move.l (a1),(a0)+
move.l d1,(a1)+
move.l (a0),d1
move.l (a1),(a0)+
move.l d1,(a1)+
move.l (a0),d1
move.l (a1),(a0)+
move.l d1,(a1)+
move.l (a0),d1
move.l (a1),(a0)+
move.l d1,(a1)+
dbra d0,2$
rts
ENDC
; Set 68020+ routines for mixing
XDEF _MixUse020
_MixUse020
IFNE SUPPORT_000&SUPPORT_020
lea mixr_020(pc),a0
lea mixr_skip(pc),a1
moveq #6,d0
1$ addq.l #8,a1
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbra d0,1$
; --- modify code directly to use the 020 MixSample routine
move.w #MixSample_020-(MixS_instr+2),MixS_instr+2
move.l a6,-(sp)
movea.l 4.w,a6
jsr -$27C(a6) ;CacheClearU()
move.l (sp)+,a6
ENDC
rts
; PlayNoteMix --- note playing
; Registers:
; D7 = track number
; D1 = note number (BYTE)
; A0 = sample pointer
; A3 = song sample data (used in OCTAMED_INTERN)
; A5 = track data structure
; Play backwards if bit #6 of trk_miscflags is set.
XDEF _PlayNoteMix
IFEQ OCTAMED_INTERN
XREF flags,rptrptlen
ENDC
_PlayNoteMix move.l a2,-(sp)
cmp.w m_channels(pc),d7
bhs.w pnm_exit
movea.l trk_cinfo(a5),a1
lea _freq_tables+32,a2
move.b trk_finetune(a5),d0
ext.w d0
add.w d0,d0
add.w d0,d0
move.l 0(a2,d0.w),a2
move.l a2,trk_periodtbl(a5)
ext.w d1 ;not > $7F anyway
add.w d1,d1
move.w 0(a2,d1.w),trk_prevper(a5) ;store frequency
IFNE OCTAMED_INTERN
btst #0,45(a3) ;SSFLG_LOOP of ss->flags?
beq.w pnm_noloop
cmp.l #2,56(a3) ;ss->replen > 2?
bls.w pnm_noloop
bset #CHFLAGB_LOOP,ci_flags(a1)
btst #3,45(a3) ;SSFLG_PINGPONG of ss->flags?
ELSEIF
moveq #0,d0
move.b trk_previnstr(a5),d0
lea flags,a3
move.b 0(a3,d0.w),d1
lea rptrptlen,a3
lsl.w #3,d0
adda.w d0,a3
btst #0,d1 ;SSFLG_LOOP?
beq.w pnm_noloop
cmp.l #2,4(a3) ;ss->replen...
bls.w pnm_noloop
bset #CHFLAGB_LOOP,ci_flags(a1)
btst #3,d1 ;SSFLG_PINGPONG of ss->flags?
ENDC
beq.s 1$
bset #CHFLAGB_PINGPONG,ci_flags(a1)
bra.s 2$
1$ bclr #CHFLAGB_PINGPONG,ci_flags(a1)
2$
IFNE OCTAMED_INTERN
move.l 40(a3),d0 ;ss->rep
move.l 56(a3),d1 ;ss->replen
ELSEIF
move.l (a3)+,d0
move.l (a3),d1
ENDC
move.l d1,ci_restartoffset(a1) ;loop length
btst #6,trk_miscflags(a5)
bne.s pnm_loopbackw
; --- loop forwards
add.l d1,d0 ;sum rep + length
move.l d0,ci_endoffset(a1) ;endoffset
moveq #0,d1
move.w trk_soffset(a5),d1 ;start offset
cmp.l d0,d1
blo.s 3$ ;start offs < end offs (valid)
moveq #0,d1 ;invalid -> clear start offset
3$ move.l d1,ci_offset(a1)
bclr #CHFLAGB_BACKW,ci_flags(a1)
bra.w pnm_loopset
; --- loop backwards
pnm_loopbackw
bset #CHFLAGB_BACKW,ci_flags(a1)
move.l (a0),d1 ;sample length
btst #4,5(a0) ;16-bit?
beq.s 1$
lsr.l #1,d1 ;/ 2, if so
1$ subq.l #1,d1
move.l d1,ci_offset(a1)
sub.l d0,d1
subq.l #1,d0
move.l d0,ci_endoffset(a1) ;ss->rep
moveq #0,d0
move.w trk_soffset(a5),d0
cmp.l d0,d1
bls.s pnm_loopset ;offs - endoffs <= trk_soffset
sub.l d0,ci_offset(a1)
bra.s pnm_loopset
; --- no loop
pnm_noloop
bclr #CHFLAGB_LOOP,ci_flags(a1)
clr.l ci_restartoffset(a1)
move.l (a0),d1 ;get sample length
btst #4,5(a0) ;16-bit?
beq.s 2$
lsr.l #1,d1 ;/ 2
2$ btst #6,trk_miscflags(a5)
beq.s pnm_oneshotforw
; --- one-shot, backwards
bset #CHFLAGB_BACKW,ci_flags(a1)
moveq #-1,d0
move.l d0,ci_endoffset(a1)
subq.l #1,d1
moveq #0,d0
move.w trk_soffset(a5),d0
sub.l d0,d1
bpl.s 3$
add.l d0,d1 ;overflow.. compensate
3$ move.l d1,ci_offset(a1)
bra.s pnm_loopset
; --- one-shot, forwards
pnm_oneshotforw
bclr #CHFLAGB_BACKW,ci_flags(a1)
move.l d1,ci_endoffset(a1)
moveq #0,d0
move.w trk_soffset(a5),d0
cmp.l d1,d0
blo.s 1$
moveq #0,d0
1$ move.l d0,ci_offset(a1)
pnm_loopset
; --- set other parameters
clr.l ci_newstart_addr(a1)
lea 6(a0),a2
move.l a2,ci_sample_start(a1)
btst #5,5(a0) ;test stereo...
beq.s 1$ ;no stereo
move.l (a0),ci_rightch_offs(a1)
bset #CHFLAGB_STEREO,ci_flags(a1)
bra.s 2$
1$ bclr #CHFLAGB_STEREO,ci_flags(a1)
clr.l ci_rightch_offs(a1)
2$ bclr #CHFLAGB_MUTED,ci_flags(a1)
btst #4,5(a0) ;16-bit??
bne.s pnm_16bit
bclr #CHFLAGB_16BIT,ci_flags(a1)
pnm_exit move.l (sp)+,a2
rts
pnm_16bit bset #CHFLAGB_16BIT,ci_flags(a1)
move.l (sp)+,a2
rts
IFNE OCTAMED_INTERN
; _PlayDataMix --- sample playing
; Registers:
; D7 = track number
; D1 = frequency (UWORD)
; D2 = offset
; D3 = length
; D4 = loop (UBYTE, boolean)
; A0 = sample pointer
XDEF _PlayDataMix
_PlayDataMix cmp.w m_channels(pc),d7
bhs.w pdm_rts
movem.l a4-a5,-(sp)
lea trackdataptrs,a1
move.w d7,d0
add.w d0,d0
add.w d0,d0
adda.w d0,a1
movea.l (a1),a5
move.w d1,trk_prevper(a5) ;store frequency
move.b #64,trk_prevvol(a5) ;full volume
movea.l trk_cinfo(a5),a1
move.l d2,ci_offset(a1)
tst.b d4 ;loop?
bne.s 1$
clr.l ci_restartoffset(a1) ;no
bclr #CHFLAGB_LOOP,ci_flags(a1)
bra.s 2$
1$ move.l d3,ci_restartoffset(a1)
bset #CHFLAGB_LOOP,ci_flags(a1)
2$ move.l d2,d0
add.l d3,d0
move.l d0,ci_endoffset(a1)
bsr.s pdm_set
move.w trk_prevper(a5),d1
bsr.w _MixSetTrkPeriod
moveq #64,d0
movea.l _sng,a0
movea.l (a0),a4 ;MixSetTrkVol needs this for pan
bsr.w _MixSetTrkVol
movem.l (sp)+,a4-a5
pdm_rts rts
pdm_set move.l a2,-(sp)
bra.s pnm_loopset
ENDC
; -------------------------------------------------------------------
; SetMixTempo(sg) (a0)
; -------------------------------------------------------------------
XDEF _SetMixTempo
_SetMixTempo btst #5,msng_flags2(a0) ;BPM?
beq.s smt_nobpm
move.l m_actualrate(pc),d0
move.b msng_flags2(a0),d1
and.w #$1F,d1 ;BPM lpb mask
addq.w #1,d1
mulu msng_deftempo(a0),d1
IFNE OCTAMED_INTERN
movea.l _UtilityBase,a0
ELSEIF
movea.l UtBase,a0
ENDC
jsr -$9C(a0) ;UDivMod32()
move.l d0,d1
lsl.l #3,d0 ;* 8
add.l d1,d0
add.l d1,d0 ;* 10
move.l d0,_passlength
rts
smt_nobpm move.l #470000,d0
divu msng_deftempo(a0),d0
mulu m_actualrate(pc),d0
lsr.l #4,d0
divu #44336,d0
moveq #0,d1
movem.w d0/d1,_passlength
rts
; -------------------------------------------------------------------
; Variables
; -------------------------------------------------------------------
; This routine copies the variables defined in C-source to here
; for local access.
XDEF _SetMixVars
IFNE OCTAMED_INTERN
XREF _sng
XREF _m_swapchan
ELSEIF
XREF _sng_struct
ENDC
XREF _mix_channels,maxaudiotrk
XREF _actualrate_hz,_actualrate_fract
XREF trackdataptrs
_SetMixVars move.w _mix_channels,d0
move.w d0,m_channels
move.w d0,maxaudiotrk
IFNE OCTAMED_INTERN
movea.l _sng,a0
movea.l (a0),a0
move.b msng_m_stereo(a0),m_stereo
ELSEIF
movea.l _sng_struct,a0
move.l 528(a0),d1 ;flags3 in MMD2song
btst #0,d1
sne m_stereo
ENDC
move.b msng_m_echo(a0),m_echo
move.b msng_m_echodep(a0),m_echodepth
move.w _actualrate_hz,m_actualrate
move.w _actualrate_fract,m_actualrfract
; --- set trk_cinfo field of track data structures
move.l _chinfo,d1
lea trackdataptrs,a0
subq.w #1,d0
bmi.s smv_rts
1$ movea.l (a0)+,a1
move.l d1,trk_cinfo(a1)
add.l #ci_sizeof,d1
dbra d0,1$
smv_rts rts
; Local variables:
m_channels ds.w 1
m_stereo ds.b 1
m_echo ds.b 1
m_echodepth ds.b 1
m_smoothing ds.b 1
m_actualrate dc.w 1 ;\ keep together
m_actualrfract ds.w 1 ;/
m_whichbuff ds.w 1
m_destbuff ds.l 4
; -------------------------------------------------------------------
; Audio Interrupts (Amiga audio output)
; -------------------------------------------------------------------
XREF _chipbuff
AudI8m move.w #$80,$9C(a0) ;clear AUD0 of INTREQ
not.b m_whichbuff-AudI8m(a5)
beq.s 1$ ;use audio buffer #1
addq.l #4,a1 ;use audio buffer #2
1$ move.l (a1),d0
move.l d0,$A0(a0) ;set ac_ptr
move.l d0,$B0(a0)
move.l d0,$C0(a0)
move.l d0,$D0(a0)
move.l d0,m_destbuff-AudI8m(a5)
lea mixsint(pc),a1
jmp -$B4(a6) ;Cause()
AudSI8m move.l a2,-(sp)
move.l (a1),a2 ;mixbuff
bsr.w _BuffFillPass
movea.l m_destbuff-AudSI8m(a5),a0
move.l _buffsize,d0
lsr.w #1,d0
subq.w #1,d0
1$ move.w (a2)+,d1
move.b (a2),d1
addq.l #2,a2
move.w d1,(a0)+
dbra d0,1$
move.l (sp)+,a2
rts
AudI14m move.w #$80,$9C(a0) ;clear AUD0 of INTREQ
not.b m_whichbuff-AudI14m(a5)
beq.s 1$ ;use audio buffer #1
addq.l #8,a1 ;use audio buffer #2
1$ move.l (a1)+,d0
move.l d0,$A0(a0) ;set ac_ptr
move.l d0,$B0(a0)
move.l (a1),d1
move.l d1,$C0(a0)
move.l d1,$D0(a0)
movem.l d0/d1,m_destbuff-AudI14m(a5)
lea mixsint(pc),a1
jmp -$B4(a6) ;Cause()
AudSI14m move.l a2,-(sp)
move.l (a1),a2 ;mixbuff
bsr.w _BuffFillPass
movem.l m_destbuff-AudSI14m(a5),a0/a1
move.l _buffsize,d0
lsr.w #1,d0
subq.w #1,d0
move.l d2,a5
1$ move.w (a2)+,d1
moveq #0,d2
move.b d1,d2
move.b (a2)+,d1
move.w d1,(a0)+
lsl.w #6,d2
move.b (a2)+,d2
lsr.b #2,d2
move.w d2,(a1)+
dbra d0,1$
move.l a5,d2
move.l (sp)+,a2
rts
AudI8s move.w #$80,$9C(a0) ;clear AUD0 of INTREQ
not.b m_whichbuff-AudI8s(a5)
beq.s 1$ ;use audio buffer #1
addq.l #8,a1 ;use audio buffer #2
1$ movem.l (a1)+,d0/d1
movem.l d0/d1,m_destbuff-AudI8s(a5)
IFNE OCTAMED_INTERN
tst.b _m_swapchan
beq.s 2$
exg d0,d1
2$
ENDC
move.l d1,$A0(a0) ;set ac_ptr
move.l d0,$B0(a0)
move.l d0,$C0(a0)
move.l d1,$D0(a0)
lea mixsint(pc),a1
jmp -$B4(a6) ;Cause()
AudSI8s move.l a2,-(sp)
move.l (a1),a2 ;mixbuff
bsr.w _BuffFillPass
movem.l m_destbuff-AudSI8s(a5),a0/a1
move.l _buffsize,d0
lsr.w #1,d0
subq.w #1,d0
1$ move.w (a2)+,d1
move.b 2(a2),d1
move.w d1,(a0)+
move.w (a2),d1
move.b 4(a2),d1
move.w d1,(a1)+
addq.l #6,a2
dbra d0,1$
move.l (sp)+,a2
rts
AudI14s move.w #$80,$9C(a0) ;clear AUD0 of INTREQ
not.b m_whichbuff-AudI14s(a5)
beq.s 1$ ;use audio buffer #1
lea 16(a1),a1 ;use audio buffer #2
1$ movem.l (a1)+,d0/d1
movem.l d0/d1,m_destbuff-AudI14s(a5)
IFNE OCTAMED_INTERN
tst.b _m_swapchan
bne.s 2$
ENDC
move.l d0,$B0(a0) ;set ac_ptr
move.l d1,$C0(a0)
movem.l (a1)+,d0/d1
movem.l d0/d1,m_destbuff+8-AudI14s(a5)
move.l d0,$A0(a0)
move.l d1,$D0(a0)
lea mixsint(pc),a1
jmp -$B4(a6) ;Cause()
IFNE OCTAMED_INTERN
2$ move.l d0,$A0(a0)
move.l d1,$D0(a0)
movem.l (a1)+,d0/d1
movem.l d0/d1,m_destbuff+8-AudI14s(a5)
move.l d0,$B0(a0) ;set ac_ptr
move.l d1,$C0(a0)
lea mixsint(pc),a1
jmp -$B4(a6) ;Cause()
ENDC
AudSI14s movem.l a2/a3/d2/d3,-(sp)
move.l (a1),a2 ;mixbuff
bsr.w _BuffFillPass
movem.l m_destbuff-AudSI14s(a5),a0/a1/a3/a5
move.l _buffsize,d0
lsr.w #1,d0
subq.w #1,d0
1$ move.w (a2)+,d1
move.b d1,d3
move.w (a2)+,d2
move.b (a2)+,d1
move.w d1,(a0)+
moveq #0,d1
move.b d3,d1
lsl.w #6,d1
move.b (a2)+,d1
lsr.b #2,d1
move.w d1,(a1)+
move.w d2,d1
move.b (a2)+,d1
move.w d1,(a3)+
moveq #0,d1
move.b d2,d1
lsl.w #6,d1
move.b (a2)+,d1
lsr.b #2,d1
move.w d1,(a5)+
dbra d0,1$
movem.l (sp)+,a2/a3/d2/d3
rts
; -------------------------------------------------------------------
; StartAmigaMix(14bit) (d2)
; -------------------------------------------------------------------
XREF _mixbuff
XDEF _StartAmigaMix
_StartAmigaMix move.l a6,-(sp)
tst.w d2
beq.s sam_8bit
tst.b m_stereo
bne.s sam_stereo14
lea AudI14m(pc),a0
lea AudSI14m(pc),a1
bra.s sam_setintr
sam_stereo14 lea AudI14s(pc),a0
lea AudSI14s(pc),a1
bra.s sam_setintr
sam_8bit tst.b m_stereo
bne.s sam_stereo
lea AudI8m(pc),a0
lea AudSI8m(pc),a1
bra.s sam_setintr
sam_stereo lea AudI8s(pc),a0
lea AudSI8s(pc),a1
sam_setintr move.l a0,mixintr
move.l a1,mixsintr
clr.b m_whichbuff
moveq #7,d0 ;INTB_AUD0
lea mixint(pc),a1
movea.l 4.w,a6
jsr -$A2(a6) ;SetIntVector
lea _chipbuff,a1
lea $dff000,a0
tst.w d2
beq.s sam_8bit2
tst.b m_stereo
beq.s sam_nostereo1
IFNE OCTAMED_INTERN
tst.b _m_swapchan
bne.s 1$
ENDC
move.l (a1)+,$B0(a0)
move.l (a1)+,$C0(a0)
move.l (a1)+,$A0(a0)
move.l (a1)+,$D0(a0)
bra.s sam_startdma
IFNE OCTAMED_INTERN
1$ move.l (a1)+,$A0(a0)
move.l (a1)+,$D0(a0)
move.l (a1)+,$B0(a0)
move.l (a1)+,$C0(a0)
bra.s sam_startdma
ENDC
sam_nostereo1 move.l (a1)+,d0
move.l d0,$B0(a0)
move.l d0,$A0(a0)
move.l (a1),d0
move.l d0,$D0(a0)
move.l d0,$C0(a0)
bra.s sam_startdma
sam_8bit2 move.l (a1)+,d0 ;chipbuff (1)
move.l d0,$B0(a0) ;to ac_ptr[1]
move.l d0,$C0(a0)
tst.b m_stereo
beq.s sam_nostereo2
IFNE OCTAMED_INTERN
tst.b _m_swapchan
beq.s 1$
move.l d0,$A0(a0)
move.l d0,$D0(a0)
move.l (a1),d0
move.l d0,$B0(a0)
move.l d0,$C0(a0)
bra.s sam_startdma
1$
ENDC
move.l (a1),d0 ;chipbuff (2)
sam_nostereo2 move.l d0,$A0(a0) ;ac_ptr[0]
move.l d0,$D0(a0)
sam_startdma move.w #$8080,$9A(a0) ;INTENA
move.w #$0080,$9C(a0) ;INTREQ (avoids spurious interrupt when turning DMA on)
move.w #$800F,$96(a0) ;DMACON
move.l (sp)+,a6
rts
mixintname dc.b 'OctaMED Mixing Interrupt',0
EVEN
mixint ds.w 5
dc.l mixintname,_chipbuff
mixintr dc.l AudI8m
mixsintname dc.b 'OctaMED Mixing SoftInt',0
EVEN
mixsint ds.w 5
dc.l mixsintname,_mixbuff
mixsintr dc.l AudSI8m
; -------------------------------------------------------------------
; BuffFillPass(WORD *mix_dest) (a2)
; -------------------------------------------------------------------
; Fills the mix buffer (calling IntHandler and mixing routines as
; required).
XREF _IntHandler
XDEF _BuffFillPass
_BuffFillPass movem.l a2/d2-d5,-(sp)
movem.w _currleft(pc),d3/d5
move.l _buffsize,d4 ;fillleft
; --- clear destination buffer
move.w d4,d0
movea.l a2,a0
tst.b m_stereo
bne.s 2$
lsr.w #1,d0
bcc.s 2$
clr.w (a0)+
1$ clr.l (a0)+
2$ dbra d0,1$
; --- loop
bfp_loop tst.l d4
beq.s bfp_exit
tst.w d3
beq.s bfp_nomix
cmp.l d3,d4 ;min(currleft,fillleft)
bls.s 1$
move.l d3,d2
bra.s 2$
1$ move.l d4,d2
2$ movea.l a2,a1
sub.w d2,d3
sub.l d2,d4
MixS_instr
IFNE SUPPORT_000
bsr.w MixSample ;will be modified for 020+
ELSEIF
bsr.w MixSample_020
ENDC
tst.b m_stereo
beq.s bfp_mono
add.l d2,d2
bfp_mono add.l d2,d2
add.l d2,a2
bfp_nomix tst.w d3
bne.s bfp_loop
jsr _IntHandler(pc)
move.w _passlength(pc),d3
add.w _passfract(pc),d5
bcc.s bfp_loop
addq.w #1,d3
bra.s bfp_loop
bfp_exit movem.w d3/d5,_currleft ;store back
movem.l (sp)+,a2/d2-d5
tst.b m_echo
beq.s bfp_noecho
movea.l a2,a0
bsr.s _Fx_Echo
bfp_noecho
IFNE OCTAMED_INTERN
movea.l _sng,a0
movea.l (a0),a0
move.b msng_m_stsep(a0),d1
beq.s bfp_rts
tst.b msng_m_stereo(a0)
beq.s bfp_rts
ELSEIF
movea.l _sng_struct,a0
move.b 540(a0),d1 ;stereosep
beq.s bfp_rts
btst #0,531(a0) ;flags3 (last byte) (STEREO flag)
beq.s bfp_rts
ENDC
movea.l a2,a0
bra.w _Fx_StereoSep
bfp_rts rts
; Variables for buffer filling.
XDEF _currleft,_currleftfract
XDEF _passlength,_passfract
_currleft dc.w 0 ;\ don't change ordering
_currleftfract dc.w 0 ;/
_passlength dc.w 0 ;\ here too
_passfract dc.w 0 ;/
; -------------------------------------------------------------------
; _Fx_Echo(WORD *mixbuff) (a0)
; -------------------------------------------------------------------
XDEF _Fx_Echo
XREF _echobuffer ;(WORD *)
XREF _echord ;(LONG)
XREF _echobuffsz ;(LONG)
_Fx_Echo movem.l d2-d6/a2,-(sp)
move.l _echobuffer,d0
beq.w fxec_return
move.l d0,a2 ;a2 = echobuffer (start)
moveq #0,d2 ;d2 = copied samples
move.l _buffsize,d3 ;d3 = mix buffer size
move.l _echord,d4 ;d4 = echobuffer position
move.l _echobuffsz,d5 ;d5 = echobuffer size
move.b m_echodepth(pc),d6 ;d6 = echo shift cnt
tst.b m_stereo
beq.w fxec_mono
cmp.b #2,m_echo
beq.w fxec_crossecho
; --- STEREO, NORMAL ECHO
fxec_loop1 cmp.l d3,d2 ;copied >= buffsize?
bhs.w fxec_return
cmp.l d5,d4 ;echord >= echobuffsz?
blo.s 1$
moveq #0,d4 ;if so, echord = 0
1$ move.l d3,d0 ;buffsize...
sub.l d2,d0 ; - copied
move.l d5,d1 ;echobuffsz
sub.l d4,d1 ; - echord
cmp.l d1,d0 ;d0 > d1?
bhs.s 2$ ;yes, lower # in d1
move.l d0,d1 ;move lower to d1 => copylen
2$ move.l d4,d0 ;echord
add.l d0,d0
add.l d0,d0 ; *= 4..
lea 0(a2,d0.l),a1 ;a1 = echo buffer pointer
add.l d1,d2 ;copied += copylen
add.l d1,d4 ;echord += copylen
lsr.l #1,d1
bcc.s 4$
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
4$ lsr.l #1,d1
bcs.s 5$
; --- echo loop
3$ subq.l #1,d1 ;copylen--
bmi.s fxec_loop1 ;end of copy
move.w (a1),d0 ;get word from echo buffer
asr.w d6,d0 ;shift...
add.w d0,(a0) ;add to mix buffer
move.w (a0)+,(a1)+ ;mix buffer -> echo buffer
move.w (a1),d0 ;the same for the right ch.
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
; --- 3 times more
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
5$ move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
bra.s 3$
fxec_return move.l d4,_echord ;store...
movem.l (sp)+,d2-d6/a2
rts
fxec_crossecho
; --- STEREO, CROSS ECHO (additive)
fxec_loop2 cmp.l d3,d2 ;copied >= buffsize?
bhs.s fxec_return
cmp.l d5,d4 ;echord >= echobuffsz?
blo.s 1$
moveq #0,d4 ;if so, echord = 0
1$ move.l d3,d0 ;buffsize...
sub.l d2,d0 ; - copied
move.l d5,d1 ;echobuffsz
sub.l d4,d1 ; - echord
cmp.l d1,d0 ;d0 > d1?
bhs.s 2$ ;yes, lower # in d1
move.l d0,d1 ;move lower to d1 => copylen
2$ move.l d4,d0 ;echord
add.l d0,d0
add.l d0,d0 ; *= 4..
lea 0(a2,d0.l),a1 ;a1 = echo buffer pointer
add.l d1,d2 ;copied += copylen
add.l d1,d4 ;echord += copylen
lsr.l #1,d1
bcc.s 4$
move.w 2(a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a1),d0
asr.w d6,d0
add.w d0,2(a0)
move.l (a0)+,(a1)+
4$ lsr.l #1,d1
bcs.s 5$
; --- echo loop
3$ subq.l #1,d1 ;copylen--
bmi.s fxec_loop2 ;end of copy
move.w 2(a1),d0 ;get word from right ch
asr.w d6,d0 ;and shift...
add.w d0,(a0) ;add to left ch
move.w (a1),d0 ;get left ch echo
asr.w d6,d0
add.w d0,2(a0) ;add to right ch
move.l (a0)+,(a1)+ ;copy the lw to echo buffer
move.w 2(a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a1),d0
asr.w d6,d0
add.w d0,2(a0)
move.l (a0)+,(a1)+
5$ move.w 2(a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a1),d0
asr.w d6,d0
add.w d0,2(a0)
move.l (a0)+,(a1)+
move.w 2(a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a1),d0
asr.w d6,d0
add.w d0,2(a0)
move.l (a0)+,(a1)+
bra.s 3$
fxec_mono
; --- MONO
fxec_loop3 cmp.l d3,d2 ;copied >= buffsize?
bhs.w fxec_return
cmp.l d5,d4 ;echord >= echobuffsz?
blo.s 1$
moveq #0,d4 ;if so, echord = 0
1$ move.l d3,d0 ;buffsize...
sub.l d2,d0 ; - copied
move.l d5,d1 ;echobuffsz
sub.l d4,d1 ; - echord
cmp.l d1,d0 ;d0 > d1?
bhs.s 2$ ;yes, lower # in d1
move.l d0,d1 ;move lower to d1 => copylen
2$ lea 0(a2,d4.l),a1 ;a1 = echo buffer pointer
add.l d4,a1 ;(index *= 2)
add.l d1,d2 ;copied += copylen
add.l d1,d4 ;echord += copylen
lsr.l #1,d1
bcc.s 4$
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
4$ lsr.l #1,d1
bcs.s 5$
; --- echo loop
3$ subq.l #1,d1 ;copylen--
bmi.s fxec_loop3 ;end of copy
move.w (a1),d0 ;get word from echo buffer
asr.w d6,d0 ;shift...
add.w d0,(a0) ;add to mix buffer
move.w (a0)+,(a1)+ ;mix buffer -> echo buffer
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
5$ move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
move.w (a1),d0
asr.w d6,d0
add.w d0,(a0)
move.w (a0)+,(a1)+
bra.s 3$
; -------------------------------------------------------------------
; _Fx_StereoSep(WORD stereosep,WORD *mixbuff) (d1, a0)
; -------------------------------------------------------------------
_Fx_StereoSep: movem.l d2/d3,-(sp)
move.l _buffsize,d0
tst.b d1
blt.s fxss_neg
moveq #5,d2
sub.b d1,d2 ;d2 = shift counter
lsr.w #1,d0
bcc.s fxss_even
move.w (a0),d1
move.w 2(a0),d3
asr.w d2,d3
sub.w d3,(a0)+
asr.w d2,d1
sub.w d1,(a0)+
fxss_even lsr.w #1,d0
bcc.s 3$ ;length divisible by 4
bra.s 2$ ;copy 2 samples first
1$ move.w (a0),d1 ;left sample
move.w 2(a0),d3 ;right sample
asr.w d2,d3 ;shift...
sub.w d3,(a0)+ ;sub from left
asr.w d2,d1
sub.w d1,(a0)+ ;sub from right
; --- loop rolled out four times
move.w (a0),d1
move.w 2(a0),d3
asr.w d2,d3
sub.w d3,(a0)+
asr.w d2,d1
sub.w d1,(a0)+
2$ move.w (a0),d1
move.w 2(a0),d3
asr.w d2,d3
sub.w d3,(a0)+
asr.w d2,d1
sub.w d1,(a0)+
move.w (a0),d1
move.w 2(a0),d3
asr.w d2,d3
sub.w d3,(a0)+
asr.w d2,d1
sub.w d1,(a0)+
3$ dbra d0,1$
movem.l (sp)+,d2/d3
rts
fxss_neg addq.b #5,d1 ;d1 = shift counter
lsr.w #1,d0
bcc.s fxss_even2
move.w (a0),d2
move.w 2(a0),d3
asr.w d1,d3
add.w d3,(a0)+
asr.w d1,d2
add.w d2,(a0)+
fxss_even2 lsr.w #1,d0
bcc.s 3$
bra.s 2$
1$ move.w (a0),d2 ;left sample
move.w 2(a0),d3 ;right sample
asr.w d1,d3 ;shift...
add.w d3,(a0)+ ;add to left
asr.w d1,d2
add.w d2,(a0)+ ;add to right
; --- rolled out
move.w (a0),d2
move.w 2(a0),d3
asr.w d1,d3
add.w d3,(a0)+
asr.w d1,d2
add.w d2,(a0)+
2$ move.w (a0),d2
move.w 2(a0),d3
asr.w d1,d3
add.w d3,(a0)+
asr.w d1,d2
add.w d2,(a0)+
move.w (a0),d2
move.w 2(a0),d3
asr.w d1,d3
add.w d3,(a0)+
asr.w d1,d2
add.w d2,(a0)+
3$ dbra d0,1$
movem.l (sp)+,d2/d3
rts
; -------------------------------------------------------------------
; Effect handling (called by the player code)
; -------------------------------------------------------------------
XDEF Mix_FX20,Mix_FX2E,Mix_FX2F
; -------------------------------------------------------------------
; Effect 20: change sample position
; D0 = position change (pos or neg), D7 = track number
; A5 = track data structure
; -------------------------------------------------------------------
Mix_FX20 cmp.w m_channels(pc),d7
bhs.s mfx20_exit
movea.l trk_cinfo(a5),a0
move.l ci_offset(a0),d1
asl.w #8,d0
ext.l d0
add.l d0,d1
bmi.s mfx20_exit ;may not become negative
cmp.l ci_endoffset(a0),d1
bhs.s mfx20_exit ;nor exceed sample end
move.l d1,ci_offset(a0)
mfx20_exit rts
; -------------------------------------------------------------------
; Effect 2E: panpot
; D4 = pan position (-16 - +16)
; A5 = track data structure
; A4 = song structure
; -------------------------------------------------------------------
IFNE OCTAMED_INTERN
XREF _needrefresh
ENDC
Mix_FX2E cmp.w m_channels(pc),d7
bhs.s mfx2e_exit
cmp.b #-16,d4
blt.s mfx2e_exit
cmp.b #16,d4
bgt.s mfx2e_exit
IFNE OCTAMED_INTERN
lea msng_trkpan(a4),a0
ELSEIF
move.l msng_trkpan(a4),d1
beq.s mfx2e_exit
movea.l d1,a0
ENDC
move.b d4,0(a0,d7.w)
IFNE OCTAMED_INTERN
or.w #$1000,_needrefresh+2 ;track pan refresh
ENDC
mfx2e_exit rts
; -------------------------------------------------------------------
; Effect 2F: effect settings
; D4 = settings data
; $Ex (x = 6 - 1) -> echo depth
; $Dx (x = C - 0 - 4) -> stereo separation
; A4 = song struct, A5 = track data structure
; -------------------------------------------------------------------
Mix_FX2F move.b d4,d0
and.b #$F0,d0
and.w #$000F,d4
cmp.b #$E0,d0
bne.s mfx2f_noEx
moveq #7,d0
sub.b d4,d0
ble.s mfx2f_exit ;< 1
cmp.b #6,d0
bgt.s mfx2f_exit ;> 6
move.b d0,m_echodepth
move.b d0,msng_m_echodep(a4)
bra.s mfx2f_upd
mfx2f_noEx cmp.b #$D0,d0
bne.s mfx2f_exit
btst #3,d4
beq.s 1$
or.w #$FFF0,d4 ;negative
1$ cmp.w #4,d4
bgt.s mfx2f_exit
cmp.w #-4,d4
blt.s mfx2f_exit
move.b d4,msng_m_stsep(a4)
mfx2f_upd
IFNE OCTAMED_INTERN
or.w #$2000,_needrefresh+2
ENDC
mfx2f_exit rts
; -------------------------------------------------------------------
; Fill a frequency table
; -------------------------------------------------------------------
; A0 = destination pointer (table size = 6 * 12 UWORDs)
; D0 = base (C-1) frequency * 65536
; D1 = ratio of successive notes * 65536
XDEF _FillFreqTable,_FillFreqTable_FP
_FillFreqTable
IFNE OCTAMED_INTERN
movea.l _UtilityBase,a1
ELSEIF
movea.l UtBase,a1
ENDC
movem.l d2-d4,-(sp)
move.l d1,d2
move.l d0,d3
moveq #6*12-1,d4
1$ move.l d3,d0
clr.w d0
swap d0
move.w d0,(a0)+ ;store frequency
move.l d2,d1
; multiply frequency (upper word) with ratio
jsr -$90(a1) ;UMult32
moveq #0,d1
move.w d3,d1
move.l d0,d3 ;store previous result
move.l d2,d0
; multiply lower word with ratio
jsr -$90(a1) ;UMult32
swap d0
add.w d3,d0 ;add the middle word..
swap d3
moveq #0,d1
addx.w d1,d3 ;and possible carry
swap d3
move.w d0,d3 ;a new frequency.
dbra d4,1$
movem.l (sp)+,d2-d4
rts
; -------------------------------------------------------------------
; A floating point version... wow!!
; (gives a bit more exact results... and of course now there's
; finally some FP code in OctaMED!! (requires an FPU))
; -------------------------------------------------------------------
_FillFreqTable_FP
; D0 = base (C-1) frequency * 65536
; used floating point regs:
; FP0 = ratio of successive notes
; FP1 = current frequency
fmove.l d0,fp1
fdiv.x #65536,fp1 ;frequency of C-1
fmove.l #1,fp0
fdiv.x #12,fp0
ftwotox fp0
moveq #6*12-1,d1
1$ fmove.l fp1,d0
move.w d0,(a0)+
fmul.x fp0,fp1
dbra d1,1$
rts
END